Changeset d2d5329 in mainline


Ignore:
Timestamp:
2014-08-14T14:21:28Z (10 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
65b09c1
Parents:
8d070710
Message:

Discover function groups and widgets.

Location:
uspace/drv/audio/hdaudio
Files:
2 added
4 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/audio/hdaudio/Makefile

    r8d070710 rd2d5329  
    3333
    3434SOURCES = \
     35        codec.c \
    3536        regif.c \
    3637        hdactl.c \
  • uspace/drv/audio/hdaudio/hdactl.c

    r8d070710 rd2d5329  
    4242#include <stdint.h>
    4343
     44#include "codec.h"
    4445#include "hdactl.h"
    4546#include "regif.h"
     
    4950        ctrl_init_wait_max = 10,
    5051        codec_enum_wait_us = 512,
    51         corb_wait_max = 10
     52        corb_wait_max = 10,
     53        rirb_wait_max = 100
    5254};
    5355
     
    231233
    232234        /* Set RINTCNT - Qemu won't read from CORB if this is zero */
    233         hda_reg16_write(&hda->regs->rintcnt, 2);
     235        hda_reg16_write(&hda->regs->rintcnt, 128);
    234236
    235237        hda->ctl->rirb_rp = 0;
     
    336338}
    337339
    338 static void hda_rirb_read(hda_t *hda)
     340static int hda_rirb_read(hda_t *hda, hda_rirb_entry_t *data, size_t count)
    339341{
    340342        size_t wp;
    341343        hda_rirb_entry_t resp;
    342344        hda_rirb_entry_t *rirb;
     345        int wcnt;
    343346
    344347        rirb = (hda_rirb_entry_t *)hda->ctl->rirb_virt;
    345348
    346         wp = hda_get_rirbwp(hda);
    347         ddf_msg(LVL_NOTE, "hda_rirb_read: wp=%d", wp);
    348         while (hda->ctl->rirb_rp != wp) {
    349                 ++hda->ctl->rirb_rp;
    350                 resp = rirb[hda->ctl->rirb_rp];
    351 
    352                 ddf_msg(LVL_NOTE, "RESPONSE resp=0x%x respex=0x%x",
    353                     resp.resp, resp.respex);
    354         }
    355 }
    356 
    357 #include "spec/codec.h"
     349        while (count > 0) {
     350                wp = hda_get_rirbwp(hda);
     351                ddf_msg(LVL_NOTE, "hda_rirb_read: wp=%d", wp);
     352                while (count > 0 && hda->ctl->rirb_rp != wp) {
     353                        ++hda->ctl->rirb_rp;
     354                        resp = rirb[hda->ctl->rirb_rp];
     355
     356                        ddf_msg(LVL_NOTE, "RESPONSE resp=0x%x respex=0x%x",
     357                            resp.resp, resp.respex);
     358                        if ((resp.respex & BIT_V(uint32_t, respex_unsol)) == 0) {
     359                                /* Solicited response */
     360                                *data++ = resp;
     361                                --count;
     362                        }
     363                }
     364
     365                if (count > 0) {
     366                        wcnt = rirb_wait_max;
     367                        while (wcnt > 0 && hda_get_rirbwp(hda) == hda->ctl->rirb_rp) {
     368                                async_usleep(100);
     369                                --wcnt;
     370                        }
     371
     372                        if (hda_get_rirbwp(hda) == hda->ctl->rirb_rp)
     373                                return ETIMEOUT;
     374                }
     375        }
     376
     377        return EOK;
     378}
     379
    358380hda_ctl_t *hda_ctl_init(hda_t *hda)
    359381{
     
    426448                goto error;
    427449
    428         uint32_t verb;
    429         verb = (0 << 28) | (0 << 20) | ((hda_get_param) << 8) | (hda_sub_nc);
    430         rc = hda_corb_write(hda, &verb, 1);
    431         ddf_msg(LVL_NOTE, "hda_corb_write -> %d", rc);
    432         rc = hda_corb_write(hda, &verb, 1);
    433         ddf_msg(LVL_NOTE, "hda_corb_write -> %d", rc);
    434         rc = hda_corb_write(hda, &verb, 1);
    435         ddf_msg(LVL_NOTE, "hda_corb_write -> %d", rc);
    436         rc = hda_corb_write(hda, &verb, 1);
    437         ddf_msg(LVL_NOTE, "hda_corb_write -> %d", rc);
    438 
    439         async_usleep(100*1000);
    440         hda_rirb_read(hda);
     450        hda->ctl->codec = hda_codec_init(hda, 0);
     451        if (hda->ctl->codec == NULL)
     452                goto error;
    441453
    442454        return ctl;
     
    447459}
    448460
     461int hda_cmd(hda_t *hda, uint32_t verb, uint32_t *resp)
     462{
     463        int rc;
     464        hda_rirb_entry_t rentry;
     465
     466        rc = hda_corb_write(hda, &verb, 1);
     467        if (rc != EOK)
     468                return rc;
     469
     470        if (resp != NULL) {
     471                rc = hda_rirb_read(hda, &rentry, 1);
     472                if (rc != EOK)
     473                        return rc;
     474
     475                /* XXX Verify that response came from the correct codec */
     476                *resp = rentry.resp;
     477        }
     478
     479        return EOK;
     480}
     481
    449482void hda_ctl_fini(hda_ctl_t *ctl)
    450483{
  • uspace/drv/audio/hdaudio/hdactl.h

    r8d070710 rd2d5329  
    4747        size_t rirb_entries;
    4848        size_t rirb_rp;
     49
     50        struct hda_codec *codec;
    4951} hda_ctl_t;
    5052
    5153extern hda_ctl_t *hda_ctl_init(hda_t *);
    5254extern void hda_ctl_fini(hda_ctl_t *);
     55extern int hda_cmd(hda_t *, uint32_t, uint32_t *);
    5356
    5457#endif
  • uspace/drv/audio/hdaudio/spec/codec.h

    r8d070710 rd2d5329  
    105105        hda_sub_nc = 0x04,
    106106        /** Function Group Type */
    107         hba_fgrp_type = 0x05,
     107        hda_fgrp_type = 0x05,
    108108        /** Audio Function Group Capabilities */
    109109        hda_afg_caps = 0x08,
     
    132132} hda_param_id_t;
    133133
     134/** Subordinate Node Count Response bits */
     135typedef enum {
     136        /** Starting Node Number (H) */
     137        subnc_startnode_h = 23,
     138        /** Starting Node Number (L) */
     139        subnc_startnode_l = 16,
     140        /** Total Node Count (H) */
     141        subnc_nodecount_h = 7,
     142        /** Total Node Count (L) */
     143        subnc_nodecount_l = 0
     144} hda_sub_nc_bits_t;
     145
     146/** Function Group Type Response bits */
     147typedef enum {
     148        /** UnSol Capable */
     149        fgrpt_unsol = 8,
     150        /** Group Type (H) */
     151        fgrpt_type_h = 7,
     152        /** Group Type (L) */
     153        fgrpt_type_l = 0
     154} hda_fgrp_type_bits_t;
     155
     156/** Function Group Type */
     157typedef enum {
     158        /** Audio Function Group */
     159        fgrp_afg = 0x01,
     160        /** Vendor Defined Modem Function Group */
     161        fgrp_vdmfg = 0x02
     162} hda_fgrp_type_t;
     163
     164/** Audio Widget Capabilities Bits */
     165typedef enum {
     166        /** Type (H) */
     167        awc_type_h = 23,
     168        /** Type (L) */
     169        awc_type_l = 20,
     170        /** Chan Count Ext (H) */
     171        awc_chan_count_ext_h = 15,
     172        /** Chan Count Ext (L) */
     173        awc_chan_count_ext_l = 13,
     174        /** CP Caps */
     175        awc_cp_caps = 12,
     176        /** L-R Swap */
     177        awc_lr_swap = 11,
     178        /** Power Control */
     179        awc_power_cntrl = 10,
     180        /** Digital */
     181        awc_digital = 9,
     182        /** Conn List */
     183        awc_conn_list = 8,
     184        /** Unsol Capable */
     185        awc_unsol_capable = 7,
     186        /** Proc Widget */
     187        awc_proc_widget = 6,
     188        /** Stripe */
     189        awc_stripe = 5,
     190        /** Format Override */
     191        awc_fmt_override = 4,
     192        /** Amp Param Override */
     193        awc_amp_param_override = 3,
     194        /** Out Amp Present */
     195        awc_out_amp_present = 2,
     196        /** In Amp Present */
     197        awc_in_amp_present = 1,
     198        /** Chan Count LSB (Stereo) */
     199        awc_chan_count_lsb = 0
     200} hda_awidget_caps_bits_t;
     201
     202/** Audio Widget Type */
     203typedef enum {
     204        /** Audio Output */
     205        awt_audio_output = 0x0,
     206        /** Audio Input */
     207        awt_audio_input = 0x1,
     208        /** Audio Mixer */
     209        awt_audio_mixer = 0x2,
     210        /** Audio Selector */
     211        awt_audio_selector = 0x3,
     212        /** Pin Complex */
     213        awt_pin_complex = 0x4,
     214        /** Power Widget */
     215        awt_power_widget = 0x5,
     216        /** Volume Knob Widget */
     217        awt_volume_knob = 0x6,
     218        /** Beep Generator Widget */
     219        awt_beep_generator = 0x7,
     220        /** Vendor-defined audio widget */
     221        awt_vendor_defined = 0xf
     222} hda_awidget_type_t;
     223
    134224#endif
    135225
Note: See TracChangeset for help on using the changeset viewer.