Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 1e92bc3 in mainline


Ignore:
Timestamp:
2014-08-26T15:32:19Z (6 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
9bae8b8
Parents:
c67195c
Message:

Enable interrupt in IRC and max all input and output amps.

Location:
uspace/drv/audio/hdaudio
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/audio/hdaudio/codec.c

    rc67195c r1e92bc3  
    156156}
    157157
     158static int hda_set_out_amp_max(hda_codec_t *codec, uint8_t aw)
     159{
     160        uint32_t ampcaps;
     161        uint32_t gmleft, gmright;
     162        uint32_t offset;
     163        int rc;
     164
     165        rc = hda_get_parameter(codec, aw,
     166            hda_out_amp_caps, &ampcaps);
     167        if (rc != EOK)
     168                goto error;
     169
     170        rc = hda_get_amp_gain_mute(codec, aw, 0x8000, &gmleft);
     171        if (rc != EOK)
     172                goto error;
     173
     174        rc = hda_get_amp_gain_mute(codec, aw, 0xc000, &gmright);
     175        if (rc != EOK)
     176                goto error;
     177
     178        ddf_msg(LVL_NOTE, "out amp caps 0x%x "
     179            "gain/mute: L:0x%x R:0x%x",
     180            ampcaps, gmleft, gmright);
     181        offset = ampcaps & 0x7f;
     182
     183        rc = hda_set_amp_gain_mute(codec, aw, 0xb000 + offset);
     184        if (rc != EOK)
     185                goto error;
     186
     187        return EOK;
     188error:
     189        return rc;
     190}
     191
     192static int hda_set_in_amp_max(hda_codec_t *codec, uint8_t aw)
     193{
     194        uint32_t ampcaps;
     195        uint32_t gmleft, gmright;
     196        uint32_t offset;
     197        int i;
     198        int rc;
     199
     200        rc = hda_get_parameter(codec, aw,
     201            hda_out_amp_caps, &ampcaps);
     202        if (rc != EOK)
     203                goto error;
     204
     205        ddf_msg(LVL_NOTE, "in amp caps 0x%x ", ampcaps);
     206        offset = ampcaps & 0x7f;
     207
     208        for (i = 0; i < 15; i++) {
     209                rc = hda_get_amp_gain_mute(codec, aw, 0x0000 + i, &gmleft);
     210                if (rc != EOK)
     211                        goto error;
     212
     213                rc = hda_get_amp_gain_mute(codec, aw, 0x4000 + i, &gmright);
     214                if (rc != EOK)
     215                        goto error;
     216
     217                ddf_msg(LVL_NOTE, "in:%d gain/mute: L:0x%x R:0x%x",
     218                    i, gmleft, gmright);
     219
     220                rc = hda_set_amp_gain_mute(codec, aw, 0x7000 + (i << 8) + offset);
     221                if (rc != EOK)
     222                        goto error;
     223        }
     224
     225        return EOK;
     226error:
     227        return rc;
     228}
     229
    158230hda_codec_t *hda_codec_init(hda_t *hda, uint8_t address)
    159231{
     
    218290                        } else if (awtype == awt_audio_output) {
    219291                                codec->out_aw = aw;
     292                                codec->out_aw_list[codec->out_aw_num++] = aw;
    220293                        }
    221294
    222                         if ((awcaps & BIT_V(uint32_t, awc_out_amp_present)) != 0) {
    223                                 uint32_t ampcaps;
    224                                 uint32_t gmleft, gmright;
    225 
    226                                 rc = hda_get_parameter(codec, aw,
    227                                     hda_out_amp_caps, &ampcaps);
    228                                 if (rc != EOK)
    229                                         goto error;
    230 
    231                                 rc = hda_get_amp_gain_mute(codec, aw, 0x8000, &gmleft);
    232                                 if (rc != EOK)
    233                                         goto error;
    234 
    235                                 rc = hda_get_amp_gain_mute(codec, aw, 0xc000, &gmright);
    236                                 if (rc != EOK)
    237                                         goto error;
    238 
    239                                 ddf_msg(LVL_NOTE, "out amp caps 0x%x "
    240                                     "gain/mute: L:0x%x R:0x%x",
    241                                     ampcaps, gmleft, gmright);
    242 
    243                                 rc = hda_set_amp_gain_mute(codec, aw, 0xb04a);
    244                                 if (rc != EOK)
    245                                         goto error;
    246                         }
     295                        if ((awcaps & BIT_V(uint32_t, awc_out_amp_present)) != 0)
     296                                hda_set_out_amp_max(codec, aw);
     297
     298                        if ((awcaps & BIT_V(uint32_t, awc_in_amp_present)) != 0)
     299                                hda_set_in_amp_max(codec, aw);
    247300                }
    248301        }
     
    275328{
    276329        int rc;
    277 
    278         /* XXX Choose appropriate parameters */
    279         uint32_t fmt;
    280         /* 48 kHz, 16-bits, 1 channel */
    281         fmt = (fmt_base_44khz << fmt_base) | (fmt_bits_16 << fmt_bits_l);
    282 
    283         /* Configure converter */
    284 
    285         ddf_msg(LVL_NOTE, "Configure converter format");
    286         rc = hda_set_converter_fmt(codec, codec->out_aw, fmt);
    287         if (rc != EOK)
    288                 goto error;
    289 
    290         ddf_msg(LVL_NOTE, "Configure converter stream, channel");
    291         rc = hda_set_converter_ctl(codec, codec->out_aw, sid, 0);
    292         if (rc != EOK)
    293                 goto error;
     330        int out_aw;
     331        int i;
     332
     333        for (i = 0; i < codec->out_aw_num; i++) {
     334                out_aw = codec->out_aw_list[i];
     335
     336                /* XXX Choose appropriate parameters */
     337                uint32_t fmt;
     338                /* 48 kHz, 16-bits, 1 channel */
     339                fmt = (fmt_base_44khz << fmt_base) | (fmt_bits_16 << fmt_bits_l);
     340
     341                /* Configure converter */
     342
     343                ddf_msg(LVL_NOTE, "Configure converter format");
     344                rc = hda_set_converter_fmt(codec, out_aw, fmt);
     345                if (rc != EOK)
     346                        goto error;
     347
     348                ddf_msg(LVL_NOTE, "Configure converter stream, channel");
     349                rc = hda_set_converter_ctl(codec, out_aw, sid, 0);
     350                if (rc != EOK)
     351                        goto error;
     352        }
    294353
    295354        return EOK;
  • uspace/drv/audio/hdaudio/codec.h

    rc67195c r1e92bc3  
    3838#include "hdaudio.h"
    3939
     40#define MAX_OUT_AW 256
     41
    4042typedef struct hda_codec {
    4143        hda_t *hda;
    4244        uint8_t address;
    4345        uint8_t out_aw;
     46        uint8_t out_aw_list[MAX_OUT_AW];
     47        int out_aw_num;
     48        int out_aw_sel;
    4449} hda_codec_t;
    4550
  • uspace/drv/audio/hdaudio/hdactl.c

    rc67195c r1e92bc3  
    5555};
    5656
     57static void hda_ctl_process_rirb(hda_ctl_t *);
     58
    5759/** Perform set-reset handshake on a 16-bit register.
    5860 *
     
    407409        int wcnt;
    408410
    409         ddf_msg(LVL_NOTE, "hda_solrb_read()");
    410         wcnt = 100;
    411 
    412         ddf_msg(LVL_NOTE, "hda_solrb_read() - lock mutex");
     411        ddf_msg(LVL_DEBUG, "hda_solrb_read()");
     412
    413413        fibril_mutex_lock(&hda->ctl->solrb_lock);
    414414
    415415        while (count > 0) {
    416                 ddf_msg(LVL_NOTE, "hda_solrb_read() - while(1)");
    417416                while (count > 0 && hda->ctl->solrb_rp != hda->ctl->solrb_wp) {
    418                         ddf_msg(LVL_NOTE, "hda_solrb_read() - while(2)");
    419417                        ++hda->ctl->solrb_rp;
    420418                        resp = hda->ctl->solrb[hda->ctl->solrb_rp];
    421419
    422                         ddf_msg(LVL_NOTE, "solrb RESPONSE resp=0x%x respex=0x%x",
     420                        ddf_msg(LVL_DEBUG2, "solrb RESPONSE resp=0x%x respex=0x%x",
    423421                            resp.resp, resp.respex);
    424422                        if ((resp.respex & BIT_V(uint32_t, respex_unsol)) == 0) {
     
    430428
    431429                if (count > 0) {
    432                         ddf_msg(LVL_NOTE, "hda_solrb_read() - count > 0");
     430                        wcnt = 100;
    433431                        while (wcnt > 0 && hda->ctl->solrb_wp == hda->ctl->solrb_rp) {
    434                                 ddf_msg(LVL_NOTE, "hda_solrb_read() - while(3), wcnt=%d", wcnt);
    435432                                fibril_mutex_unlock(&hda->ctl->solrb_lock);
    436                                 ddf_msg(LVL_NOTE, "hda_solrb_read() - sleep");
    437433                                async_usleep(10000);
    438                                 ddf_msg(LVL_NOTE, "hda_solrb_read() - re-lock");
    439434                                fibril_mutex_lock(&hda->ctl->solrb_lock);
    440435                                --wcnt;
     
    442437
    443438                        if (hda->ctl->solrb_wp == hda->ctl->solrb_rp) {
     439                                ddf_msg(LVL_NOTE, "hda_solrb_read() - last ditch effort process RIRB");
     440                                fibril_mutex_unlock(&hda->ctl->solrb_lock);
     441                                hda_ctl_process_rirb(hda->ctl);
     442                                fibril_mutex_lock(&hda->ctl->solrb_lock);
     443                        }
     444
     445                        if (hda->ctl->solrb_wp == hda->ctl->solrb_rp) {
    444446                                ddf_msg(LVL_NOTE, "hda_solrb_read() time out");
    445                                 ddf_msg(LVL_NOTE, "corbwp=%d corbrp=%d",
    446                                     hda_reg16_read(&hda->regs->corbwp),
    447                                     hda_reg16_read(&hda->regs->corbrp));
    448                                 ddf_msg(LVL_NOTE, "corbctl=0x%x, corbsts=0x%x",
    449                                     hda_reg8_read(&hda->regs->corbctl),
    450                                     hda_reg8_read(&hda->regs->corbsts));
    451                                 ddf_msg(LVL_NOTE, "rirbwp=%d",
    452                                     hda_reg16_read(&hda->regs->rirbwp));
    453                                 ddf_msg(LVL_NOTE, "rirbctl=0x%x, rirbsts=0x%x",
    454                                     hda_reg8_read(&hda->regs->rirbctl),
    455                                     hda_reg8_read(&hda->regs->rirbsts));
    456447                                fibril_mutex_unlock(&hda->ctl->solrb_lock);
    457448                                return ETIMEOUT;
     
    461452
    462453        fibril_mutex_unlock(&hda->ctl->solrb_lock);
    463         ddf_msg(LVL_NOTE, "hda_solrb_read() success");
    464454        return EOK;
    465455}
     
    613603}
    614604
    615 void hda_ctl_interrupt(hda_ctl_t *ctl)
     605static void hda_ctl_process_rirb(hda_ctl_t *ctl)
    616606{
    617607        hda_rirb_entry_t resp;
     
    625615                }
    626616
    627                 ddf_msg(LVL_NOTE, "writing to solrb");
     617                ddf_msg(LVL_DEBUG2, "writing to solrb");
    628618                fibril_mutex_lock(&ctl->solrb_lock);
    629619                ctl->solrb_wp = (ctl->solrb_wp + 1) % softrb_entries;
     
    634624}
    635625
     626void hda_ctl_interrupt(hda_ctl_t *ctl)
     627{
     628        hda_ctl_process_rirb(ctl);
     629}
     630
    636631/** @}
    637632 */
  • uspace/drv/audio/hdaudio/hdaudio.c

    rc67195c r1e92bc3  
    3737#include <ddi.h>
    3838#include <device/hw_res_parsed.h>
     39#include <irc.h>
    3940#include <stdio.h>
    4041#include <errno.h>
     
    255256        ddf_msg(LVL_NOTE, "range0.base=%x", hdaudio_irq_pio_ranges[0].base);
    256257
     258        rc = irc_enable_interrupt(res.irqs.irqs[0]);
     259        if (rc != EOK) {
     260                ddf_msg(LVL_ERROR, "Failed enabling interrupt. (%d)", rc);
     261                goto error;
     262        }
     263
    257264        rc = register_interrupt_handler(dev, res.irqs.irqs[0],
    258265            hdaudio_interrupt, &irq_code);
  • uspace/drv/audio/hdaudio/pcm_iface.c

    rc67195c r1e92bc3  
    256256
    257257        if (hda->ev_sess == NULL) {
    258                 ddf_log_warning("No one listening for event %u", event);
     258                if (0) ddf_log_warning("No one listening for event %u", event);
    259259                return;
    260260        }
Note: See TracChangeset for help on using the changeset viewer.