summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorZhao Edgar Liu - Sun Microsystems <Edgar.Liu@Sun.COM>2009-12-01 10:01:20 +0800
committerZhao Edgar Liu - Sun Microsystems <Edgar.Liu@Sun.COM>2009-12-01 10:01:20 +0800
commitc7b817cf7bb73e4c5318fd6f3324fee960f0ce54 (patch)
tree0d8f64d9201c31ee349de6c6a80fcfc80778a359 /usr/src
parent4a508a79352d55b18841bdb18d6d7b4153b6c03a (diff)
downloadillumos-joyent-c7b817cf7bb73e4c5318fd6f3324fee960f0ce54.tar.gz
6862294 Clicking from speakers whilst changing volume level
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/common/io/audio/drv/audiohd/audiohd.c138
-rw-r--r--usr/src/uts/common/io/audio/drv/audiohd/audiohd.h31
2 files changed, 50 insertions, 119 deletions
diff --git a/usr/src/uts/common/io/audio/drv/audiohd/audiohd.c b/usr/src/uts/common/io/audio/drv/audiohd/audiohd.c
index 1a517bcdeb..de637a220f 100644
--- a/usr/src/uts/common/io/audio/drv/audiohd/audiohd.c
+++ b/usr/src/uts/common/io/audio/drv/audiohd/audiohd.c
@@ -1699,6 +1699,7 @@ audiohd_configure_output(audiohd_state_t *statep)
audiohd_set_output_gain(statep);
}
+
static void
audiohd_configure_input(audiohd_state_t *statep)
{
@@ -1708,19 +1709,18 @@ audiohd_configure_input(audiohd_state_t *statep)
audiohd_set_pin_volume(statep, DTYPE_CD);
audiohd_set_pin_volume(statep, DTYPE_MIC_IN);
}
+
static int
audiohd_set_volume(void *arg, uint64_t val)
{
audiohd_ctrl_t *pc = arg;
audiohd_state_t *statep = pc->statep;
- val &= 0xff;
- if (val > 100)
- return (EINVAL);
+ AUDIOHD_CHECK_CHANNEL_VOLUME(val);
mutex_enter(&statep->hda_mutex);
pc->val = val;
- audiohd_configure_output(statep);
+ audiohd_set_output_gain(statep);
mutex_exit(&statep->hda_mutex);
return (0);
@@ -1747,15 +1747,7 @@ audiohd_set_rear(void *arg, uint64_t val)
{
audiohd_ctrl_t *pc = arg;
audiohd_state_t *statep = pc->statep;
- uint8_t l, r;
-
- if (val & ~0xffff)
- return (EINVAL);
-
- l = (val & 0xff00) >> 8;
- r = (val & 0xff);
- if ((l > 100) || (r > 100))
- return (EINVAL);
+ AUDIOHD_CHECK_2CHANNELS_VOLUME(val);
mutex_enter(&statep->hda_mutex);
pc->val = val;
@@ -1770,11 +1762,7 @@ audiohd_set_center(void *arg, uint64_t val)
{
audiohd_ctrl_t *pc = arg;
audiohd_state_t *statep = pc->statep;
-
- val &= 0xff;
-
- if (val > 100)
- return (EINVAL);
+ AUDIOHD_CHECK_CHANNEL_VOLUME(val);
mutex_enter(&statep->hda_mutex);
pc->val = val;
@@ -1789,15 +1777,7 @@ audiohd_set_surround(void *arg, uint64_t val)
{
audiohd_ctrl_t *pc = arg;
audiohd_state_t *statep = pc->statep;
- uint8_t l, r;
-
- if (val & ~0xffff)
- return (EINVAL);
-
- l = (val & 0xff00) >> 8;
- r = (val & 0xff);
- if ((l > 100) || (r > 100))
- return (EINVAL);
+ AUDIOHD_CHECK_2CHANNELS_VOLUME(val);
mutex_enter(&statep->hda_mutex);
pc->val = val;
@@ -1812,11 +1792,7 @@ audiohd_set_lfe(void *arg, uint64_t val)
{
audiohd_ctrl_t *pc = arg;
audiohd_state_t *statep = pc->statep;
-
- val &= 0xff;
-
- if (val > 100)
- return (EINVAL);
+ AUDIOHD_CHECK_CHANNEL_VOLUME(val);
mutex_enter(&statep->hda_mutex);
pc->val = val;
@@ -1830,15 +1806,7 @@ audiohd_set_speaker(void *arg, uint64_t val)
{
audiohd_ctrl_t *pc = arg;
audiohd_state_t *statep = pc->statep;
- uint8_t l, r;
-
- if (val & ~0xffff)
- return (EINVAL);
-
- l = (val & 0xff00) >> 8;
- r = (val & 0xff);
- if ((l > 100) || (r > 100))
- return (EINVAL);
+ AUDIOHD_CHECK_2CHANNELS_VOLUME(val);
mutex_enter(&statep->hda_mutex);
pc->val = val;
@@ -1852,15 +1820,7 @@ audiohd_set_front(void *arg, uint64_t val)
{
audiohd_ctrl_t *pc = arg;
audiohd_state_t *statep = pc->statep;
- uint8_t l, r;
-
- if (val & ~0xffff)
- return (EINVAL);
-
- l = (val & 0xff00) >> 8;
- r = (val & 0xff);
- if ((l > 100) || (r > 100))
- return (EINVAL);
+ AUDIOHD_CHECK_2CHANNELS_VOLUME(val);
mutex_enter(&statep->hda_mutex);
pc->val = val;
@@ -1874,15 +1834,7 @@ audiohd_set_headphone(void *arg, uint64_t val)
{
audiohd_ctrl_t *pc = arg;
audiohd_state_t *statep = pc->statep;
- uint8_t l, r;
-
- if (val & ~0xffff)
- return (EINVAL);
-
- l = (val & 0xff00) >> 8;
- r = (val & 0xff);
- if ((l > 100) || (r > 100))
- return (EINVAL);
+ AUDIOHD_CHECK_2CHANNELS_VOLUME(val);
mutex_enter(&statep->hda_mutex);
pc->val = val;
@@ -1896,15 +1848,7 @@ audiohd_set_linein(void *arg, uint64_t val)
{
audiohd_ctrl_t *pc = arg;
audiohd_state_t *statep = pc->statep;
- uint8_t l, r;
-
- if (val & ~0xffff)
- return (EINVAL);
-
- l = (val & 0xff00) >> 8;
- r = (val & 0xff);
- if ((l > 100) || (r > 100))
- return (EINVAL);
+ AUDIOHD_CHECK_2CHANNELS_VOLUME(val);
mutex_enter(&statep->hda_mutex);
pc->val = val;
@@ -1919,15 +1863,7 @@ audiohd_set_mic(void *arg, uint64_t val)
{
audiohd_ctrl_t *pc = arg;
audiohd_state_t *statep = pc->statep;
- uint8_t l, r;
-
- if (val & ~0xffff)
- return (EINVAL);
-
- l = (val & 0xff00) >> 8;
- r = (val & 0xff);
- if ((l > 100) || (r > 100))
- return (EINVAL);
+ AUDIOHD_CHECK_2CHANNELS_VOLUME(val);
mutex_enter(&statep->hda_mutex);
pc->val = val;
@@ -1942,15 +1878,7 @@ audiohd_set_cd(void *arg, uint64_t val)
{
audiohd_ctrl_t *pc = arg;
audiohd_state_t *statep = pc->statep;
- uint8_t l, r;
-
- if (val & ~0xffff)
- return (EINVAL);
-
- l = (val & 0xff00) >> 8;
- r = (val & 0xff);
- if ((l > 100) || (r > 100))
- return (EINVAL);
+ AUDIOHD_CHECK_2CHANNELS_VOLUME(val);
mutex_enter(&statep->hda_mutex);
pc->val = val;
@@ -1965,15 +1893,7 @@ audiohd_set_mongain(void *arg, uint64_t val)
{
audiohd_ctrl_t *pc = arg;
audiohd_state_t *statep = pc->statep;
- uint8_t l, r;
-
- if (val & ~0xffff)
- return (EINVAL);
-
- l = (val & 0xff00) >> 8;
- r = (val & 0xff);
- if ((l > 100) || (r > 100))
- return (EINVAL);
+ AUDIOHD_CHECK_2CHANNELS_VOLUME(val);
mutex_enter(&statep->hda_mutex);
pc->val = val;
@@ -1988,11 +1908,7 @@ audiohd_set_beep(void *arg, uint64_t val)
{
audiohd_ctrl_t *pc = arg;
audiohd_state_t *statep = pc->statep;
-
- val &= 0xff;
-
- if (val > 100)
- return (EINVAL);
+ AUDIOHD_CHECK_CHANNEL_VOLUME(val);
mutex_enter(&statep->hda_mutex);
pc->val = val;
@@ -2378,9 +2294,10 @@ audiohd_beep_freq(void *arg, int freq)
static int
audiohd_init_state(audiohd_state_t *statep, dev_info_t *dip)
{
- audio_dev_t *adev;
+ audio_dev_t *adev;
statep->hda_dip = dip;
+ statep->hda_rirb_rp = 0;
if ((adev = audio_dev_alloc(dip, 0)) == NULL) {
audio_dev_warn(statep->adev,
@@ -2396,8 +2313,6 @@ audiohd_init_state(audiohd_state_t *statep, dev_info_t *dip)
audio_dev_set_description(adev, AUDIOHD_DEV_CONFIG);
audio_dev_set_version(adev, AUDIOHD_DEV_VERSION);
- statep->hda_rirb_rp = 0;
-
return (DDI_SUCCESS);
} /* audiohd_init_state() */
@@ -2415,17 +2330,17 @@ audiohd_init_pci(audiohd_state_t *statep, ddi_device_acc_attr_t *acc_attr)
uint16_t vid;
uint8_t cTmp;
dev_info_t *dip = statep->hda_dip;
- audio_dev_t *ahandle = statep->adev;
+ audio_dev_t *adev = statep->adev;
if (pci_config_setup(dip, &statep->hda_pci_handle) == DDI_FAILURE) {
- audio_dev_warn(ahandle,
+ audio_dev_warn(adev,
"pci config mapping failed");
return (DDI_FAILURE);
}
if (ddi_regs_map_setup(dip, 1, &statep->hda_reg_base, 0,
0, acc_attr, &statep->hda_reg_handle) != DDI_SUCCESS) {
- audio_dev_warn(ahandle,
+ audio_dev_warn(adev,
"memory I/O mapping failed");
return (DDI_FAILURE);
}
@@ -2439,7 +2354,6 @@ audiohd_init_pci(audiohd_state_t *statep, ddi_device_acc_attr_t *acc_attr)
vid = pci_config_get16(statep->hda_pci_handle, PCI_CONF_VENID);
switch (vid) {
-
case AUDIOHD_VID_INTEL:
/*
* Currently, Intel (G)MCH and ICHx chipsets support PCI
@@ -2459,7 +2373,6 @@ audiohd_init_pci(audiohd_state_t *statep, ddi_device_acc_attr_t *acc_attr)
pci_config_put8(statep->hda_pci_handle,
AUDIOHD_INTEL_PCI_TCSEL, (cTmp & AUDIOHD_INTEL_TCS_MASK));
break;
-
case AUDIOHD_VID_ATI:
/*
* Refer to ATI SB450 datesheet. We set snoop for SB450
@@ -2480,7 +2393,6 @@ audiohd_init_pci(audiohd_state_t *statep, ddi_device_acc_attr_t *acc_attr)
pci_config_put8(statep->hda_pci_handle, AUDIOHD_CORB_SIZE_OFF,
cTmp | AUDIOHD_NVIDIA_SNOOP);
break;
-
default:
break;
}
@@ -2778,12 +2690,10 @@ audiohd_init_controller(audiohd_state_t *statep)
statep->hda_streams_nums = statep->hda_input_streams +
statep->hda_output_streams;
-
statep->hda_record_regbase = AUDIOHD_REG_SD_BASE;
statep->hda_play_regbase = AUDIOHD_REG_SD_BASE + AUDIOHD_REG_SD_LEN *
statep->hda_input_streams;
-
/* stop all dma before starting to reset controller */
audiohd_stop_dma(statep);
@@ -2823,8 +2733,7 @@ audiohd_init_controller(audiohd_state_t *statep)
/* Initialize RIRB */
addr = statep->hda_dma_rirb.ad_paddr;
AUDIOHD_REG_SET32(AUDIOHD_REG_RIRBLBASE, (uint32_t)addr);
- AUDIOHD_REG_SET32(AUDIOHD_REG_RIRBUBASE,
- (uint32_t)(addr >> 32));
+ AUDIOHD_REG_SET32(AUDIOHD_REG_RIRBUBASE, (uint32_t)(addr >> 32));
AUDIOHD_REG_SET16(AUDIOHD_REG_RIRBWP, AUDIOHDR_RIRBWP_RESET);
AUDIOHD_REG_SET8(AUDIOHD_REG_RIRBSIZE, AUDIOHDR_RIRBSZ_256);
AUDIOHD_REG_SET8(AUDIOHD_REG_RIRBCTL, AUDIOHDR_RIRBCTL_DMARUN |
@@ -2834,8 +2743,7 @@ audiohd_init_controller(audiohd_state_t *statep)
addr = statep->hda_dma_corb.ad_paddr;
AUDIOHD_REG_SET16(AUDIOHD_REG_CORBRP, AUDIOHDR_CORBRP_RESET);
AUDIOHD_REG_SET32(AUDIOHD_REG_CORBLBASE, (uint32_t)addr);
- AUDIOHD_REG_SET32(AUDIOHD_REG_CORBUBASE,
- (uint32_t)(addr >> 32));
+ AUDIOHD_REG_SET32(AUDIOHD_REG_CORBUBASE, (uint32_t)(addr >> 32));
AUDIOHD_REG_SET8(AUDIOHD_REG_CORBSIZE, AUDIOHDR_CORBSZ_256);
AUDIOHD_REG_SET16(AUDIOHD_REG_CORBWP, 0);
AUDIOHD_REG_SET16(AUDIOHD_REG_CORBRP, 0);
diff --git a/usr/src/uts/common/io/audio/drv/audiohd/audiohd.h b/usr/src/uts/common/io/audio/drv/audiohd/audiohd.h
index 955c1aa0b1..e1da2332f7 100644
--- a/usr/src/uts/common/io/audio/drv/audiohd/audiohd.h
+++ b/usr/src/uts/common/io/audio/drv/audiohd/audiohd.h
@@ -796,13 +796,13 @@ struct audiohd_state {
uint32_t hda_flags;
boolean_t soft_volume;
- boolean_t intr_added;
- caddr_t hda_reg_base;
- ddi_acc_handle_t hda_pci_handle;
- ddi_acc_handle_t hda_reg_handle;
+ caddr_t hda_reg_base;
+ ddi_acc_handle_t hda_pci_handle;
+ ddi_acc_handle_t hda_reg_handle;
ddi_intr_handle_t *htable; /* For array of interrupts */
+ boolean_t intr_added;
int intr_type; /* What type of interrupt */
int intr_rqst; /* # of request intrs count */
int intr_cnt; /* # of intrs count returned */
@@ -985,6 +985,29 @@ struct audiohd_state {
return (DDI_FAILURE); \
}
+/*
+ * check volume adjust value of 2 channels control
+ */
+#define AUDIOHD_CHECK_2CHANNELS_VOLUME(value) \
+{ \
+ if ((value) & ~0xffff) \
+ return (EINVAL); \
+ if ((((value) & 0xff00) >> 8) > 100 || \
+ ((value) & 0xff) > 100) \
+ return (EINVAL); \
+}
+
+/*
+ * check volume adjust value of mono channel control
+ */
+#define AUDIOHD_CHECK_CHANNEL_VOLUME(value) \
+{ \
+ if ((value) & ~0xff) \
+ return (EINVAL); \
+ if (((value) & 0xff) > 100) \
+ return (EINVAL); \
+}
+
#ifdef __cplusplus
}
#endif