2007-10-26 23:54:54 +04:00
/*
* Handlers for board audio hooks , splitted from bttv - cards
*
* Copyright ( c ) 2006 Mauro Carvalho Chehab ( mchehab @ infradead . org )
* This code is placed under the terms of the GNU General Public License
*/
2007-10-27 00:21:30 +04:00
# include "bttv-audio-hook.h"
2006-08-25 23:53:04 +04:00
# include <linux/delay.h>
2007-10-26 23:54:54 +04:00
/* ----------------------------------------------------------------------- */
/* winview */
2006-08-25 23:53:04 +04:00
void winview_volume ( struct bttv * btv , __u16 volume )
2007-10-26 23:54:54 +04:00
{
/* PT2254A programming Jon Tombs, jon@gte.esi.us.es */
int bits_out , loops , vol , data ;
/* 32 levels logarithmic */
2006-08-25 23:53:04 +04:00
vol = 32 - ( ( volume > > 11 ) ) ;
2007-10-26 23:54:54 +04:00
/* units */
bits_out = ( PT2254_DBS_IN_2 > > ( vol % 5 ) ) ;
/* tens */
bits_out | = ( PT2254_DBS_IN_10 > > ( vol / 5 ) ) ;
bits_out | = PT2254_L_CHANNEL | PT2254_R_CHANNEL ;
data = gpio_read ( ) ;
data & = ~ ( WINVIEW_PT2254_CLK | WINVIEW_PT2254_DATA |
WINVIEW_PT2254_STROBE ) ;
for ( loops = 17 ; loops > = 0 ; loops - - ) {
if ( bits_out & ( 1 < < loops ) )
data | = WINVIEW_PT2254_DATA ;
else
data & = ~ WINVIEW_PT2254_DATA ;
gpio_write ( data ) ;
udelay ( 5 ) ;
data | = WINVIEW_PT2254_CLK ;
gpio_write ( data ) ;
udelay ( 5 ) ;
data & = ~ WINVIEW_PT2254_CLK ;
gpio_write ( data ) ;
}
data | = WINVIEW_PT2254_STROBE ;
data & = ~ WINVIEW_PT2254_DATA ;
gpio_write ( data ) ;
udelay ( 10 ) ;
data & = ~ WINVIEW_PT2254_STROBE ;
gpio_write ( data ) ;
}
/* ----------------------------------------------------------------------- */
/* mono/stereo control for various cards (which don't use i2c chips but */
/* connect something to the GPIO pins */
2006-08-25 23:53:04 +04:00
void gvbctv3pci_audio ( struct bttv * btv , struct v4l2_tuner * t , int set )
2007-10-26 23:54:54 +04:00
{
unsigned int con = 0 ;
if ( set ) {
gpio_inout ( 0x300 , 0x300 ) ;
2006-08-25 23:53:04 +04:00
if ( t - > audmode & V4L2_TUNER_MODE_LANG1 )
2007-10-26 23:54:54 +04:00
con = 0x000 ;
2006-08-25 23:53:04 +04:00
if ( t - > audmode & V4L2_TUNER_MODE_LANG2 )
2007-10-26 23:54:54 +04:00
con = 0x300 ;
2006-08-25 23:53:04 +04:00
if ( t - > audmode & V4L2_TUNER_MODE_STEREO )
2007-10-26 23:54:54 +04:00
con = 0x200 ;
2006-08-25 23:53:04 +04:00
/* if (t->audmode & V4L2_TUNER_MODE_MONO)
2007-10-26 23:54:54 +04:00
* con = 0x100 ; */
gpio_bits ( 0x300 , con ) ;
} else {
2006-08-25 23:53:04 +04:00
t - > audmode = V4L2_TUNER_MODE_STEREO |
V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2 ;
2007-10-26 23:54:54 +04:00
}
}
2006-08-25 23:53:04 +04:00
void gvbctv5pci_audio ( struct bttv * btv , struct v4l2_tuner * t , int set )
2007-10-26 23:54:54 +04:00
{
unsigned int val , con ;
if ( btv - > radio_user )
return ;
val = gpio_read ( ) ;
if ( set ) {
con = 0x000 ;
2006-08-25 23:53:04 +04:00
if ( t - > audmode & V4L2_TUNER_MODE_LANG2 ) {
if ( t - > audmode & V4L2_TUNER_MODE_LANG1 ) {
2007-10-26 23:54:54 +04:00
/* LANG1 + LANG2 */
con = 0x100 ;
}
else {
/* LANG2 */
con = 0x300 ;
}
}
if ( con ! = ( val & 0x300 ) ) {
gpio_bits ( 0x300 , con ) ;
if ( bttv_gpio )
bttv_gpio_tracking ( btv , " gvbctv5pci " ) ;
}
} else {
switch ( val & 0x70 ) {
case 0x10 :
2006-08-25 23:53:07 +04:00
t - > rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2 ;
2007-10-26 23:54:54 +04:00
break ;
case 0x30 :
2006-08-25 23:53:07 +04:00
t - > rxsubchans = V4L2_TUNER_SUB_LANG2 ;
2007-10-26 23:54:54 +04:00
break ;
case 0x50 :
2006-08-25 23:53:07 +04:00
t - > rxsubchans = V4L2_TUNER_SUB_LANG1 ;
2007-10-26 23:54:54 +04:00
break ;
case 0x60 :
2006-08-25 23:53:07 +04:00
t - > rxsubchans = V4L2_TUNER_SUB_STEREO ;
2007-10-26 23:54:54 +04:00
break ;
case 0x70 :
2006-08-25 23:53:07 +04:00
t - > rxsubchans = V4L2_TUNER_SUB_MONO ;
2007-10-26 23:54:54 +04:00
break ;
default :
2006-08-25 23:53:07 +04:00
t - > rxsubchans = V4L2_TUNER_SUB_MONO |
2007-11-01 07:16:04 +03:00
V4L2_TUNER_SUB_STEREO |
V4L2_TUNER_SUB_LANG1 |
V4L2_TUNER_SUB_LANG2 ;
2007-10-26 23:54:54 +04:00
}
2006-08-25 23:53:07 +04:00
t - > audmode = V4L2_TUNER_MODE_STEREO |
V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2 ;
2007-10-26 23:54:54 +04:00
}
}
/*
* Mario Medina Nussbaum < medisoft @ alohabbs . org . mx >
* I discover that on BT848_GPIO_DATA address a byte 0xcce enable stereo ,
* 0xdde enables mono and 0xccd enables sap
*
* Petr Vandrovec < VANDROVE @ vc . cvut . cz >
* P . S . : At least mask in line above is wrong - GPIO pins 3 , 2 select
* input / output sound connection , so both must be set for output mode .
*
* Looks like it ' s needed only for the " tvphone " , the " tvphone 98 "
* handles this with a tda9840
*
*/
2006-08-25 23:53:04 +04:00
void avermedia_tvphone_audio ( struct bttv * btv , struct v4l2_tuner * t , int set )
2007-10-26 23:54:54 +04:00
{
int val = 0 ;
if ( set ) {
2006-08-25 23:53:04 +04:00
if ( t - > audmode & V4L2_TUNER_MODE_LANG2 ) /* SAP */
2007-10-26 23:54:54 +04:00
val = 0x02 ;
2006-08-25 23:53:04 +04:00
if ( t - > audmode & V4L2_TUNER_MODE_STEREO )
2007-10-26 23:54:54 +04:00
val = 0x01 ;
if ( val ) {
gpio_bits ( 0x03 , val ) ;
if ( bttv_gpio )
bttv_gpio_tracking ( btv , " avermedia " ) ;
}
} else {
2006-08-25 23:53:04 +04:00
t - > audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO |
V4L2_TUNER_MODE_LANG1 ;
2007-10-26 23:54:54 +04:00
return ;
}
}
2006-08-25 23:53:04 +04:00
void avermedia_tv_stereo_audio ( struct bttv * btv , struct v4l2_tuner * t , int set )
2007-10-26 23:54:54 +04:00
{
int val = 0 ;
if ( set ) {
2006-08-25 23:53:04 +04:00
if ( t - > audmode & V4L2_TUNER_MODE_LANG2 ) /* SAP */
2007-10-26 23:54:54 +04:00
val = 0x01 ;
2006-08-25 23:53:04 +04:00
if ( t - > audmode & V4L2_TUNER_MODE_STEREO ) /* STEREO */
2007-10-26 23:54:54 +04:00
val = 0x02 ;
btaor ( val , ~ 0x03 , BT848_GPIO_DATA ) ;
if ( bttv_gpio )
bttv_gpio_tracking ( btv , " avermedia " ) ;
} else {
2006-08-25 23:53:04 +04:00
t - > audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO |
V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2 ;
2007-10-26 23:54:54 +04:00
return ;
}
}
/* Lifetec 9415 handling */
2006-08-25 23:53:04 +04:00
void lt9415_audio ( struct bttv * btv , struct v4l2_tuner * t , int set )
2007-10-26 23:54:54 +04:00
{
int val = 0 ;
if ( gpio_read ( ) & 0x4000 ) {
2006-08-25 23:53:04 +04:00
t - > audmode = V4L2_TUNER_MODE_MONO ;
2007-10-26 23:54:54 +04:00
return ;
}
if ( set ) {
2006-08-25 23:53:04 +04:00
if ( t - > audmode & V4L2_TUNER_MODE_LANG2 ) /* A2 SAP */
2007-10-26 23:54:54 +04:00
val = 0x0080 ;
2006-08-25 23:53:04 +04:00
if ( t - > audmode & V4L2_TUNER_MODE_STEREO ) /* A2 stereo */
2007-10-26 23:54:54 +04:00
val = 0x0880 ;
2006-08-25 23:53:04 +04:00
if ( ( t - > audmode & V4L2_TUNER_MODE_LANG1 ) | |
( t - > audmode & V4L2_TUNER_MODE_MONO ) )
2007-10-26 23:54:54 +04:00
val = 0 ;
gpio_bits ( 0x0880 , val ) ;
if ( bttv_gpio )
bttv_gpio_tracking ( btv , " lt9415 " ) ;
} else {
/* autodetect doesn't work with this card :-( */
2006-08-25 23:53:04 +04:00
t - > audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO |
V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2 ;
2007-10-26 23:54:54 +04:00
return ;
}
}
/* TDA9821 on TerraTV+ Bt848, Bt878 */
2006-08-25 23:53:04 +04:00
void terratv_audio ( struct bttv * btv , struct v4l2_tuner * t , int set )
2007-10-26 23:54:54 +04:00
{
unsigned int con = 0 ;
if ( set ) {
gpio_inout ( 0x180000 , 0x180000 ) ;
2006-08-25 23:53:04 +04:00
if ( t - > audmode & V4L2_TUNER_MODE_LANG2 )
2007-10-26 23:54:54 +04:00
con = 0x080000 ;
2006-08-25 23:53:04 +04:00
if ( t - > audmode & V4L2_TUNER_MODE_STEREO )
2007-10-26 23:54:54 +04:00
con = 0x180000 ;
gpio_bits ( 0x180000 , con ) ;
if ( bttv_gpio )
bttv_gpio_tracking ( btv , " terratv " ) ;
} else {
2006-08-25 23:53:04 +04:00
t - > audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO |
V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2 ;
2007-10-26 23:54:54 +04:00
}
}
2006-08-25 23:53:04 +04:00
void winfast2000_audio ( struct bttv * btv , struct v4l2_tuner * t , int set )
2007-10-26 23:54:54 +04:00
{
unsigned long val = 0 ;
if ( set ) {
/*btor (0xc32000, BT848_GPIO_OUT_EN);*/
2006-08-25 23:53:04 +04:00
if ( t - > audmode & V4L2_TUNER_MODE_MONO ) /* Mono */
2007-10-26 23:54:54 +04:00
val = 0x420000 ;
2006-08-25 23:53:04 +04:00
if ( t - > audmode & V4L2_TUNER_MODE_LANG1 ) /* Mono */
2007-10-26 23:54:54 +04:00
val = 0x420000 ;
2006-08-25 23:53:04 +04:00
if ( t - > audmode & V4L2_TUNER_MODE_LANG2 ) /* SAP */
2007-10-26 23:54:54 +04:00
val = 0x410000 ;
2006-08-25 23:53:04 +04:00
if ( t - > audmode & V4L2_TUNER_MODE_STEREO ) /* Stereo */
2007-10-26 23:54:54 +04:00
val = 0x020000 ;
if ( val ) {
gpio_bits ( 0x430000 , val ) ;
if ( bttv_gpio )
bttv_gpio_tracking ( btv , " winfast2000 " ) ;
}
} else {
2006-08-25 23:53:04 +04:00
t - > audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO |
V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2 ;
2007-10-26 23:54:54 +04:00
}
}
/*
* Dariusz Kowalewski < darekk @ automex . pl >
* sound control for Prolink PV - BT878P + 9 B ( PixelView PlayTV Pro FM + NICAM
* revision 9 B has on - board TDA9874A sound decoder ) .
*
* Note : There are card variants without tda9874a . Forcing the " stereo sound route "
* will mute this cards .
*/
2006-08-25 23:53:04 +04:00
void pvbt878p9b_audio ( struct bttv * btv , struct v4l2_tuner * t , int set )
2007-10-26 23:54:54 +04:00
{
unsigned int val = 0 ;
if ( btv - > radio_user )
return ;
if ( set ) {
2006-08-25 23:53:04 +04:00
if ( t - > audmode & V4L2_TUNER_MODE_MONO ) {
2007-10-26 23:54:54 +04:00
val = 0x01 ;
}
2006-08-25 23:53:04 +04:00
if ( ( t - > audmode & ( V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2 ) )
| | ( t - > audmode & V4L2_TUNER_MODE_STEREO ) ) {
2007-10-26 23:54:54 +04:00
val = 0x02 ;
}
if ( val ) {
gpio_bits ( 0x03 , val ) ;
if ( bttv_gpio )
bttv_gpio_tracking ( btv , " pvbt878p9b " ) ;
}
} else {
2006-08-25 23:53:04 +04:00
t - > audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO |
V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2 ;
2007-10-26 23:54:54 +04:00
}
}
/*
* Dariusz Kowalewski < darekk @ automex . pl >
* sound control for FlyVideo 2000 S ( with tda9874 decoder )
* based on pvbt878p9b_audio ( ) - this is not tested , please fix ! ! !
*/
2006-08-25 23:53:04 +04:00
void fv2000s_audio ( struct bttv * btv , struct v4l2_tuner * t , int set )
2007-10-26 23:54:54 +04:00
{
unsigned int val = 0xffff ;
if ( btv - > radio_user )
return ;
if ( set ) {
2006-08-25 23:53:04 +04:00
if ( t - > audmode & V4L2_TUNER_MODE_MONO ) {
2007-10-26 23:54:54 +04:00
val = 0x0000 ;
}
2006-08-25 23:53:04 +04:00
if ( ( t - > audmode & ( V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2 ) )
| | ( t - > audmode & V4L2_TUNER_MODE_STEREO ) ) {
2007-10-26 23:54:54 +04:00
val = 0x1080 ; /*-dk-???: 0x0880, 0x0080, 0x1800 ... */
}
if ( val ! = 0xffff ) {
gpio_bits ( 0x1800 , val ) ;
if ( bttv_gpio )
bttv_gpio_tracking ( btv , " fv2000s " ) ;
}
} else {
2006-08-25 23:53:04 +04:00
t - > audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO |
V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2 ;
2007-10-26 23:54:54 +04:00
}
}
/*
* sound control for Canopus WinDVR PCI
* Masaki Suzuki < masaki @ btree . org >
*/
2006-08-25 23:53:04 +04:00
void windvr_audio ( struct bttv * btv , struct v4l2_tuner * t , int set )
2007-10-26 23:54:54 +04:00
{
unsigned long val = 0 ;
if ( set ) {
2006-08-25 23:53:04 +04:00
if ( t - > audmode & V4L2_TUNER_MODE_MONO )
2007-10-26 23:54:54 +04:00
val = 0x040000 ;
2006-08-25 23:53:04 +04:00
if ( t - > audmode & V4L2_TUNER_MODE_LANG1 )
2007-10-26 23:54:54 +04:00
val = 0 ;
2006-08-25 23:53:04 +04:00
if ( t - > audmode & V4L2_TUNER_MODE_LANG2 )
2007-10-26 23:54:54 +04:00
val = 0x100000 ;
2006-08-25 23:53:04 +04:00
if ( t - > audmode & V4L2_TUNER_MODE_STEREO )
2007-10-26 23:54:54 +04:00
val = 0 ;
if ( val ) {
gpio_bits ( 0x140000 , val ) ;
if ( bttv_gpio )
bttv_gpio_tracking ( btv , " windvr " ) ;
}
} else {
2006-08-25 23:53:04 +04:00
t - > audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO |
V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2 ;
2007-10-26 23:54:54 +04:00
}
}
/*
* sound control for AD - TVK503
* Hiroshi Takekawa < sian @ big . or . jp >
*/
2006-08-25 23:53:04 +04:00
void adtvk503_audio ( struct bttv * btv , struct v4l2_tuner * t , int set )
2007-10-26 23:54:54 +04:00
{
unsigned int con = 0xffffff ;
/* btaor(0x1e0000, ~0x1e0000, BT848_GPIO_OUT_EN); */
if ( set ) {
/* btor(***, BT848_GPIO_OUT_EN); */
2006-08-25 23:53:04 +04:00
if ( t - > audmode & V4L2_TUNER_MODE_LANG1 )
2007-10-26 23:54:54 +04:00
con = 0x00000000 ;
2006-08-25 23:53:04 +04:00
if ( t - > audmode & V4L2_TUNER_MODE_LANG2 )
2007-10-26 23:54:54 +04:00
con = 0x00180000 ;
2006-08-25 23:53:04 +04:00
if ( t - > audmode & V4L2_TUNER_MODE_STEREO )
2007-10-26 23:54:54 +04:00
con = 0x00000000 ;
2006-08-25 23:53:04 +04:00
if ( t - > audmode & V4L2_TUNER_MODE_MONO )
2007-10-26 23:54:54 +04:00
con = 0x00060000 ;
if ( con ! = 0xffffff ) {
gpio_bits ( 0x1e0000 , con ) ;
if ( bttv_gpio )
bttv_gpio_tracking ( btv , " adtvk503 " ) ;
}
} else {
2006-08-25 23:53:04 +04:00
t - > audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO |
V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2 ;
2007-10-26 23:54:54 +04:00
}
}