Re: [PATCH] Nova-S-Plus audio line input
On Sat, 2010-08-07 at 10:29 -0400, Andy Walls wrote: On Sat, 2010-07-31 at 16:37 +0200, lawrence rust wrote: Hi everyone, This patch adds audio DMA capture and ALSA mixer elements for the line input jack of the Hauppauge Nova-S-plus DVB-S PCI card. I'm using a Hauppauge Nova-S-plus PCI card to watch sat TV and it's been very robust - thanks to everyone here. I have one minor niggle - when I use it with composite video input from an external STB I can't connect the audio to the line input jack on the card. So I developed this patch, originally in late 2008 with lots of feedback and input from Darron Broad. The Nova-S-plus has a WM8775 ADC that is currently not detected. This patch enables this chip and exports elements for ALSA mixer controls. I've used this patch with kernels from 2.6.24 to 2.6.35-rc6 and I'm just a little tired of tweaking it every time a new kernel comes out so I'm hoping that it can be permanently included. Signed-off by Lawrence Rust lawrence (at) softsystem.co.uk diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c index 33082c9..044516b 100644 --- a/drivers/media/video/cx88/cx88-alsa.c +++ b/drivers/media/video/cx88/cx88-alsa.c @@ -588,6 +588,30 @@ static int snd_cx88_volume_put(struct snd_kcontrol *kcontrol, int changed = 0; u32 old; +/* If a WM8775 is used for audio input utilise the audio controls */ +if ( core-board.audio_chip core-board.audio_chip == V4L2_IDENT_WM8775) { +struct v4l2_control client_ctl; + +if ( value-value.integer.value[0] = value-value.integer.value[1]) { +v = value-value.integer.value[0] 10; +b = value-value.integer.value[0] ? + (0x8000 * value-value.integer.value[1]) / value-value.integer.value[0] : + 0x8000; +} else { +v = value-value.integer.value[1] 10; +b = value-value.integer.value[1] ? + 0x - (0x8000 * value-value.integer.value[0]) / value-value.integer.value[1] : + 0x8000; +} +client_ctl.value = v; +client_ctl.id = V4L2_CID_AUDIO_VOLUME; +call_all(core, core, s_ctrl, client_ctl); + +client_ctl.value = b; +client_ctl.id = V4L2_CID_AUDIO_BALANCE; +call_all(core, core, s_ctrl, client_ctl); +} + With the subdev construct, there is really no need for the conditional check on the chip's existence. Just do the call_all(). Or better yet, when the audio control subdevice is instantiated, squirrel away a v4l2_subdev * to it in the card's instance structure and just use that instead of call_all(). Or when the subdev is instantiated, mark the subdev's grp_id with some sort of WM8775 or audio control marker value and call the subdev by grp_ip match. Using call_all() isn't the best thing to do, when you know you're just after one or two specific devices. OK, saving the v4l2_subdev * at instantiation looks best. left = value-value.integer.value[0] 0x3f; right = value-value.integer.value[1] 0x3f; b = right - left; @@ -601,10 +625,10 @@ static int snd_cx88_volume_put(struct snd_kcontrol *kcontrol, spin_lock_irq(chip-reg_lock); old = cx_read(AUD_VOL_CTL); if (v != (old 0x3f)) { - cx_write(AUD_VOL_CTL, (old ~0x3f) | v); +cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, (old ~0x3f) | v); changed = 1; } - if (cx_read(AUD_BAL_CTL) != b) { +if ((cx_read(AUD_BAL_CTL) 0x7f) != b) { cx_write(AUD_BAL_CTL, b); changed = 1; } @@ -619,7 +643,7 @@ static struct snd_kcontrol_new snd_cx88_volume = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, - .name = Playback Volume, + .name = Tuner Volume, I'd call this Analog TV Capture Volume myself, but meh, it doesn't really matter. I thought long and hard about this name to find something meaningful. The problem I found was that many of the ALSA mixer GUIs leave little space for the name or just truncate it. Analog-TV Volume might work - avoiding the word break. I'll play with this some more. .info = snd_cx88_volume_info, .get = snd_cx88_volume_get, .put = snd_cx88_volume_put, @@ -650,7 +674,14 @@ static int snd_cx88_switch_put(struct snd_kcontrol *kcontrol, vol = cx_read(AUD_VOL_CTL); if (value-value.integer.value[0] != !(vol bit)) { vol ^= bit; - cx_write(AUD_VOL_CTL, vol); +cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, vol); +/* If a WM8775 is used for audio input utilise the audio controls */ +if ( (16) == bit core-board.audio_chip core-board.audio_chip == V4L2_IDENT_WM8775) { +struct v4l2_control client_ctl; +
Re: [PATCH] Nova-S-Plus audio line input
On Sat, 2010-07-31 at 16:37 +0200, lawrence rust wrote: Hi everyone, This patch adds audio DMA capture and ALSA mixer elements for the line input jack of the Hauppauge Nova-S-plus DVB-S PCI card. I'm using a Hauppauge Nova-S-plus PCI card to watch sat TV and it's been very robust - thanks to everyone here. I have one minor niggle - when I use it with composite video input from an external STB I can't connect the audio to the line input jack on the card. So I developed this patch, originally in late 2008 with lots of feedback and input from Darron Broad. The Nova-S-plus has a WM8775 ADC that is currently not detected. This patch enables this chip and exports elements for ALSA mixer controls. I've used this patch with kernels from 2.6.24 to 2.6.35-rc6 and I'm just a little tired of tweaking it every time a new kernel comes out so I'm hoping that it can be permanently included. Signed-off by Lawrence Rust lawrence (at) softsystem.co.uk diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c index 33082c9..044516b 100644 --- a/drivers/media/video/cx88/cx88-alsa.c +++ b/drivers/media/video/cx88/cx88-alsa.c @@ -588,6 +588,30 @@ static int snd_cx88_volume_put(struct snd_kcontrol *kcontrol, int changed = 0; u32 old; +/* If a WM8775 is used for audio input utilise the audio controls */ +if ( core-board.audio_chip core-board.audio_chip == V4L2_IDENT_WM8775) { +struct v4l2_control client_ctl; + +if ( value-value.integer.value[0] = value-value.integer.value[1]) { +v = value-value.integer.value[0] 10; +b = value-value.integer.value[0] ? + (0x8000 * value-value.integer.value[1]) / value-value.integer.value[0] : + 0x8000; +} else { +v = value-value.integer.value[1] 10; +b = value-value.integer.value[1] ? + 0x - (0x8000 * value-value.integer.value[0]) / value-value.integer.value[1] : + 0x8000; +} +client_ctl.value = v; +client_ctl.id = V4L2_CID_AUDIO_VOLUME; +call_all(core, core, s_ctrl, client_ctl); + +client_ctl.value = b; +client_ctl.id = V4L2_CID_AUDIO_BALANCE; +call_all(core, core, s_ctrl, client_ctl); +} + With the subdev construct, there is really no need for the conditional check on the chip's existence. Just do the call_all(). Or better yet, when the audio control subdevice is instantiated, squirrel away a v4l2_subdev * to it in the card's instance structure and just use that instead of call_all(). Or when the subdev is instantiated, mark the subdev's grp_id with some sort of WM8775 or audio control marker value and call the subdev by grp_ip match. Using call_all() isn't the best thing to do, when you know you're just after one or two specific devices. left = value-value.integer.value[0] 0x3f; right = value-value.integer.value[1] 0x3f; b = right - left; @@ -601,10 +625,10 @@ static int snd_cx88_volume_put(struct snd_kcontrol *kcontrol, spin_lock_irq(chip-reg_lock); old = cx_read(AUD_VOL_CTL); if (v != (old 0x3f)) { - cx_write(AUD_VOL_CTL, (old ~0x3f) | v); +cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, (old ~0x3f) | v); changed = 1; } - if (cx_read(AUD_BAL_CTL) != b) { +if ((cx_read(AUD_BAL_CTL) 0x7f) != b) { cx_write(AUD_BAL_CTL, b); changed = 1; } @@ -619,7 +643,7 @@ static struct snd_kcontrol_new snd_cx88_volume = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, - .name = Playback Volume, + .name = Tuner Volume, I'd call this Analog TV Capture Volume myself, but meh, it doesn't really matter. .info = snd_cx88_volume_info, .get = snd_cx88_volume_get, .put = snd_cx88_volume_put, @@ -650,7 +674,14 @@ static int snd_cx88_switch_put(struct snd_kcontrol *kcontrol, vol = cx_read(AUD_VOL_CTL); if (value-value.integer.value[0] != !(vol bit)) { vol ^= bit; - cx_write(AUD_VOL_CTL, vol); +cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, vol); +/* If a WM8775 is used for audio input utilise the audio controls */ +if ( (16) == bit core-board.audio_chip core-board.audio_chip == V4L2_IDENT_WM8775) { +struct v4l2_control client_ctl; +client_ctl.value = 0 == value-value.integer.value[0]; +client_ctl.id = V4L2_CID_AUDIO_MUTE; +call_all(core, core, s_ctrl, client_ctl); +} My previous comment abouit calling subdevs applies here. ret = 1; } spin_unlock_irq(chip-reg_lock); @@ -659,7 +690,7 @@ static int snd_cx88_switch_put(struct snd_kcontrol *kcontrol, static struct snd_kcontrol_new
Re: [PATCH] Nova-S-Plus audio line input
In message 1281191356.2400.91.ca...@localhost, Andy Walls wrote: LO On Sat, 2010-07-31 at 16:37 +0200, lawrence rust wrote: SNIP Sorry for the major snip but I am just filling you in with some history on this thread nothing more. I have no intention of contributing anything new. The patch by Lawrence contains some ideas from here: http://hg.kewl.org/pub/v4l-dvb-20081120/rev/c1d603af3bef As you may read, this is a copy/paste of the wm8739.c codec for the wm8775.c. There is no major effort or work involved there and makes the wm8775 behave similarly to the 8739 if I recall correctly. This was 20 months ago so I cannot recall much. Another component is from here: http://hg.kewl.org/pub/v4l-dvb-20081120/rev/302d51bf2baf It should be understood that this is also very old and i2c has had major reworking since so it should be updated if possible Lawrence and I am sure Andy has put on the right path. One other part is probably this: http://hg.kewl.org/pub/v4l-dvb-20081120/rev/8b24b8211fc9 But I can't tell really, as like Andy says there is far too much in that patchset to really consume at once. All the best, good luck darron -- // / {:)==={ Darron Broad dar...@kewl.org \\ \ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html