aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/tvaudio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/tvaudio.c')
-rw-r--r--drivers/media/video/tvaudio.c154
1 files changed, 104 insertions, 50 deletions
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index 4efb01bb44ac..356bff455ad1 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -30,10 +30,10 @@
30#include <linux/init.h> 30#include <linux/init.h>
31#include <linux/smp_lock.h> 31#include <linux/smp_lock.h>
32 32
33#include <media/audiochip.h> 33#include <media/tvaudio.h>
34#include <media/v4l2-common.h> 34#include <media/v4l2-common.h>
35 35
36#include "tvaudio.h" 36#include <media/i2c-addr.h>
37 37
38/* ---------------------------------------------------------------------- */ 38/* ---------------------------------------------------------------------- */
39/* insmod args */ 39/* insmod args */
@@ -102,7 +102,7 @@ struct CHIPDESC {
102 102
103 /* input switch register + values for v4l inputs */ 103 /* input switch register + values for v4l inputs */
104 int inputreg; 104 int inputreg;
105 int inputmap[8]; 105 int inputmap[4];
106 int inputmute; 106 int inputmute;
107 int inputmask; 107 int inputmask;
108}; 108};
@@ -119,9 +119,10 @@ struct CHIPSTATE {
119 audiocmd shadow; 119 audiocmd shadow;
120 120
121 /* current settings */ 121 /* current settings */
122 __u16 left,right,treble,bass,mode; 122 __u16 left,right,treble,bass,muted,mode;
123 int prevmode; 123 int prevmode;
124 int radio; 124 int radio;
125 int input;
125 126
126 /* thread */ 127 /* thread */
127 pid_t tpid; 128 pid_t tpid;
@@ -137,14 +138,14 @@ struct CHIPSTATE {
137/* i2c addresses */ 138/* i2c addresses */
138 139
139static unsigned short normal_i2c[] = { 140static unsigned short normal_i2c[] = {
140 I2C_TDA8425 >> 1, 141 I2C_ADDR_TDA8425 >> 1,
141 I2C_TEA6300 >> 1, 142 I2C_ADDR_TEA6300 >> 1,
142 I2C_TEA6420 >> 1, 143 I2C_ADDR_TEA6420 >> 1,
143 I2C_TDA9840 >> 1, 144 I2C_ADDR_TDA9840 >> 1,
144 I2C_TDA985x_L >> 1, 145 I2C_ADDR_TDA985x_L >> 1,
145 I2C_TDA985x_H >> 1, 146 I2C_ADDR_TDA985x_H >> 1,
146 I2C_TDA9874 >> 1, 147 I2C_ADDR_TDA9874 >> 1,
147 I2C_PIC16C54 >> 1, 148 I2C_ADDR_PIC16C54 >> 1,
148 I2C_CLIENT_END }; 149 I2C_CLIENT_END };
149I2C_CLIENT_INSMOD; 150I2C_CLIENT_INSMOD;
150 151
@@ -1101,9 +1102,8 @@ static int tda8425_shift12(int val) { return (val >> 12) | 0xf0; }
1101static int tda8425_initialize(struct CHIPSTATE *chip) 1102static int tda8425_initialize(struct CHIPSTATE *chip)
1102{ 1103{
1103 struct CHIPDESC *desc = chiplist + chip->type; 1104 struct CHIPDESC *desc = chiplist + chip->type;
1104 int inputmap[8] = { /* tuner */ TDA8425_S1_CH2, /* radio */ TDA8425_S1_CH1, 1105 int inputmap[4] = { /* tuner */ TDA8425_S1_CH2, /* radio */ TDA8425_S1_CH1,
1105 /* extern */ TDA8425_S1_CH1, /* intern */ TDA8425_S1_OFF, 1106 /* extern */ TDA8425_S1_CH1, /* intern */ TDA8425_S1_OFF};
1106 /* off */ TDA8425_S1_OFF, /* on */ TDA8425_S1_CH2};
1107 1107
1108 if (chip->c.adapter->id == I2C_HW_B_RIVA) { 1108 if (chip->c.adapter->id == I2C_HW_B_RIVA) {
1109 memcpy (desc->inputmap, inputmap, sizeof (inputmap)); 1109 memcpy (desc->inputmap, inputmap, sizeof (inputmap));
@@ -1269,8 +1269,8 @@ static struct CHIPDESC chiplist[] = {
1269 .name = "tda9840", 1269 .name = "tda9840",
1270 .id = I2C_DRIVERID_TDA9840, 1270 .id = I2C_DRIVERID_TDA9840,
1271 .insmodopt = &tda9840, 1271 .insmodopt = &tda9840,
1272 .addr_lo = I2C_TDA9840 >> 1, 1272 .addr_lo = I2C_ADDR_TDA9840 >> 1,
1273 .addr_hi = I2C_TDA9840 >> 1, 1273 .addr_hi = I2C_ADDR_TDA9840 >> 1,
1274 .registers = 5, 1274 .registers = 5,
1275 1275
1276 .checkit = tda9840_checkit, 1276 .checkit = tda9840_checkit,
@@ -1286,8 +1286,8 @@ static struct CHIPDESC chiplist[] = {
1286 .id = I2C_DRIVERID_TDA9873, 1286 .id = I2C_DRIVERID_TDA9873,
1287 .checkit = tda9873_checkit, 1287 .checkit = tda9873_checkit,
1288 .insmodopt = &tda9873, 1288 .insmodopt = &tda9873,
1289 .addr_lo = I2C_TDA985x_L >> 1, 1289 .addr_lo = I2C_ADDR_TDA985x_L >> 1,
1290 .addr_hi = I2C_TDA985x_H >> 1, 1290 .addr_hi = I2C_ADDR_TDA985x_H >> 1,
1291 .registers = 3, 1291 .registers = 3,
1292 .flags = CHIP_HAS_INPUTSEL, 1292 .flags = CHIP_HAS_INPUTSEL,
1293 1293
@@ -1298,7 +1298,7 @@ static struct CHIPDESC chiplist[] = {
1298 .init = { 4, { TDA9873_SW, 0xa4, 0x06, 0x03 } }, 1298 .init = { 4, { TDA9873_SW, 0xa4, 0x06, 0x03 } },
1299 .inputreg = TDA9873_SW, 1299 .inputreg = TDA9873_SW,
1300 .inputmute = TDA9873_MUTE | TDA9873_AUTOMUTE, 1300 .inputmute = TDA9873_MUTE | TDA9873_AUTOMUTE,
1301 .inputmap = {0xa0, 0xa2, 0xa0, 0xa0, 0xc0}, 1301 .inputmap = {0xa0, 0xa2, 0xa0, 0xa0},
1302 .inputmask = TDA9873_INP_MASK|TDA9873_MUTE|TDA9873_AUTOMUTE, 1302 .inputmask = TDA9873_INP_MASK|TDA9873_MUTE|TDA9873_AUTOMUTE,
1303 1303
1304 }, 1304 },
@@ -1308,8 +1308,8 @@ static struct CHIPDESC chiplist[] = {
1308 .checkit = tda9874a_checkit, 1308 .checkit = tda9874a_checkit,
1309 .initialize = tda9874a_initialize, 1309 .initialize = tda9874a_initialize,
1310 .insmodopt = &tda9874a, 1310 .insmodopt = &tda9874a,
1311 .addr_lo = I2C_TDA9874 >> 1, 1311 .addr_lo = I2C_ADDR_TDA9874 >> 1,
1312 .addr_hi = I2C_TDA9874 >> 1, 1312 .addr_hi = I2C_ADDR_TDA9874 >> 1,
1313 1313
1314 .getmode = tda9874a_getmode, 1314 .getmode = tda9874a_getmode,
1315 .setmode = tda9874a_setmode, 1315 .setmode = tda9874a_setmode,
@@ -1319,8 +1319,8 @@ static struct CHIPDESC chiplist[] = {
1319 .name = "tda9850", 1319 .name = "tda9850",
1320 .id = I2C_DRIVERID_TDA9850, 1320 .id = I2C_DRIVERID_TDA9850,
1321 .insmodopt = &tda9850, 1321 .insmodopt = &tda9850,
1322 .addr_lo = I2C_TDA985x_L >> 1, 1322 .addr_lo = I2C_ADDR_TDA985x_L >> 1,
1323 .addr_hi = I2C_TDA985x_H >> 1, 1323 .addr_hi = I2C_ADDR_TDA985x_H >> 1,
1324 .registers = 11, 1324 .registers = 11,
1325 1325
1326 .getmode = tda985x_getmode, 1326 .getmode = tda985x_getmode,
@@ -1332,8 +1332,8 @@ static struct CHIPDESC chiplist[] = {
1332 .name = "tda9855", 1332 .name = "tda9855",
1333 .id = I2C_DRIVERID_TDA9855, 1333 .id = I2C_DRIVERID_TDA9855,
1334 .insmodopt = &tda9855, 1334 .insmodopt = &tda9855,
1335 .addr_lo = I2C_TDA985x_L >> 1, 1335 .addr_lo = I2C_ADDR_TDA985x_L >> 1,
1336 .addr_hi = I2C_TDA985x_H >> 1, 1336 .addr_hi = I2C_ADDR_TDA985x_H >> 1,
1337 .registers = 11, 1337 .registers = 11,
1338 .flags = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE, 1338 .flags = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE,
1339 1339
@@ -1357,8 +1357,8 @@ static struct CHIPDESC chiplist[] = {
1357 .name = "tea6300", 1357 .name = "tea6300",
1358 .id = I2C_DRIVERID_TEA6300, 1358 .id = I2C_DRIVERID_TEA6300,
1359 .insmodopt = &tea6300, 1359 .insmodopt = &tea6300,
1360 .addr_lo = I2C_TEA6300 >> 1, 1360 .addr_lo = I2C_ADDR_TEA6300 >> 1,
1361 .addr_hi = I2C_TEA6300 >> 1, 1361 .addr_hi = I2C_ADDR_TEA6300 >> 1,
1362 .registers = 6, 1362 .registers = 6,
1363 .flags = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE | CHIP_HAS_INPUTSEL, 1363 .flags = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE | CHIP_HAS_INPUTSEL,
1364 1364
@@ -1379,8 +1379,8 @@ static struct CHIPDESC chiplist[] = {
1379 .id = I2C_DRIVERID_TEA6300, 1379 .id = I2C_DRIVERID_TEA6300,
1380 .initialize = tea6320_initialize, 1380 .initialize = tea6320_initialize,
1381 .insmodopt = &tea6320, 1381 .insmodopt = &tea6320,
1382 .addr_lo = I2C_TEA6300 >> 1, 1382 .addr_lo = I2C_ADDR_TEA6300 >> 1,
1383 .addr_hi = I2C_TEA6300 >> 1, 1383 .addr_hi = I2C_ADDR_TEA6300 >> 1,
1384 .registers = 8, 1384 .registers = 8,
1385 .flags = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE | CHIP_HAS_INPUTSEL, 1385 .flags = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE | CHIP_HAS_INPUTSEL,
1386 1386
@@ -1400,8 +1400,8 @@ static struct CHIPDESC chiplist[] = {
1400 .name = "tea6420", 1400 .name = "tea6420",
1401 .id = I2C_DRIVERID_TEA6420, 1401 .id = I2C_DRIVERID_TEA6420,
1402 .insmodopt = &tea6420, 1402 .insmodopt = &tea6420,
1403 .addr_lo = I2C_TEA6420 >> 1, 1403 .addr_lo = I2C_ADDR_TEA6420 >> 1,
1404 .addr_hi = I2C_TEA6420 >> 1, 1404 .addr_hi = I2C_ADDR_TEA6420 >> 1,
1405 .registers = 1, 1405 .registers = 1,
1406 .flags = CHIP_HAS_INPUTSEL, 1406 .flags = CHIP_HAS_INPUTSEL,
1407 1407
@@ -1413,8 +1413,8 @@ static struct CHIPDESC chiplist[] = {
1413 .name = "tda8425", 1413 .name = "tda8425",
1414 .id = I2C_DRIVERID_TDA8425, 1414 .id = I2C_DRIVERID_TDA8425,
1415 .insmodopt = &tda8425, 1415 .insmodopt = &tda8425,
1416 .addr_lo = I2C_TDA8425 >> 1, 1416 .addr_lo = I2C_ADDR_TDA8425 >> 1,
1417 .addr_hi = I2C_TDA8425 >> 1, 1417 .addr_hi = I2C_ADDR_TDA8425 >> 1,
1418 .registers = 9, 1418 .registers = 9,
1419 .flags = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE | CHIP_HAS_INPUTSEL, 1419 .flags = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE | CHIP_HAS_INPUTSEL,
1420 1420
@@ -1437,8 +1437,8 @@ static struct CHIPDESC chiplist[] = {
1437 .name = "pic16c54 (PV951)", 1437 .name = "pic16c54 (PV951)",
1438 .id = I2C_DRIVERID_PIC16C54_PV9, 1438 .id = I2C_DRIVERID_PIC16C54_PV9,
1439 .insmodopt = &pic16c54, 1439 .insmodopt = &pic16c54,
1440 .addr_lo = I2C_PIC16C54 >> 1, 1440 .addr_lo = I2C_ADDR_PIC16C54 >> 1,
1441 .addr_hi = I2C_PIC16C54>> 1, 1441 .addr_hi = I2C_ADDR_PIC16C54>> 1,
1442 .registers = 2, 1442 .registers = 2,
1443 .flags = CHIP_HAS_INPUTSEL, 1443 .flags = CHIP_HAS_INPUTSEL,
1444 1444
@@ -1446,8 +1446,7 @@ static struct CHIPDESC chiplist[] = {
1446 .inputmap = {PIC16C54_MISC_SND_NOTMUTE|PIC16C54_MISC_SWITCH_TUNER, 1446 .inputmap = {PIC16C54_MISC_SND_NOTMUTE|PIC16C54_MISC_SWITCH_TUNER,
1447 PIC16C54_MISC_SND_NOTMUTE|PIC16C54_MISC_SWITCH_LINE, 1447 PIC16C54_MISC_SND_NOTMUTE|PIC16C54_MISC_SWITCH_LINE,
1448 PIC16C54_MISC_SND_NOTMUTE|PIC16C54_MISC_SWITCH_LINE, 1448 PIC16C54_MISC_SND_NOTMUTE|PIC16C54_MISC_SWITCH_LINE,
1449 PIC16C54_MISC_SND_MUTE,PIC16C54_MISC_SND_MUTE, 1449 PIC16C54_MISC_SND_MUTE},
1450 PIC16C54_MISC_SND_NOTMUTE},
1451 .inputmute = PIC16C54_MISC_SND_MUTE, 1450 .inputmute = PIC16C54_MISC_SND_MUTE,
1452 }, 1451 },
1453 { 1452 {
@@ -1456,8 +1455,8 @@ static struct CHIPDESC chiplist[] = {
1456 /*.id = I2C_DRIVERID_TA8874Z, */ 1455 /*.id = I2C_DRIVERID_TA8874Z, */
1457 .checkit = ta8874z_checkit, 1456 .checkit = ta8874z_checkit,
1458 .insmodopt = &ta8874z, 1457 .insmodopt = &ta8874z,
1459 .addr_lo = I2C_TDA9840 >> 1, 1458 .addr_lo = I2C_ADDR_TDA9840 >> 1,
1460 .addr_hi = I2C_TDA9840 >> 1, 1459 .addr_hi = I2C_ADDR_TDA9840 >> 1,
1461 .registers = 2, 1460 .registers = 2,
1462 1461
1463 .getmode = ta8874z_getmode, 1462 .getmode = ta8874z_getmode,
@@ -1583,28 +1582,40 @@ static int chip_detach(struct i2c_client *client)
1583 return 0; 1582 return 0;
1584} 1583}
1585 1584
1585static int tvaudio_set_ctrl(struct CHIPSTATE *chip, struct v4l2_control *ctrl)
1586{
1587 struct CHIPDESC *desc = chiplist + chip->type;
1588
1589 switch (ctrl->id) {
1590 case V4L2_CID_AUDIO_MUTE:
1591 if (ctrl->value < 0 || ctrl->value >= 2)
1592 return -ERANGE;
1593 chip->muted = ctrl->value;
1594 if (chip->muted)
1595 chip_write_masked(chip,desc->inputreg,desc->inputmute,desc->inputmask);
1596 else
1597 chip_write_masked(chip,desc->inputreg,
1598 desc->inputmap[chip->input],desc->inputmask);
1599 break;
1600 default:
1601 return -EINVAL;
1602 }
1603 return 0;
1604}
1605
1606
1586/* ---------------------------------------------------------------------- */ 1607/* ---------------------------------------------------------------------- */
1587/* video4linux interface */ 1608/* video4linux interface */
1588 1609
1589static int chip_command(struct i2c_client *client, 1610static int chip_command(struct i2c_client *client,
1590 unsigned int cmd, void *arg) 1611 unsigned int cmd, void *arg)
1591{ 1612{
1592 __u16 *sarg = arg;
1593 struct CHIPSTATE *chip = i2c_get_clientdata(client); 1613 struct CHIPSTATE *chip = i2c_get_clientdata(client);
1594 struct CHIPDESC *desc = chiplist + chip->type; 1614 struct CHIPDESC *desc = chiplist + chip->type;
1595 1615
1596 v4l_dbg(1, debug, &chip->c, "%s: chip_command 0x%x\n", chip->c.name, cmd); 1616 v4l_dbg(1, debug, &chip->c, "%s: chip_command 0x%x\n", chip->c.name, cmd);
1597 1617
1598 switch (cmd) { 1618 switch (cmd) {
1599 case AUDC_SET_INPUT:
1600 if (desc->flags & CHIP_HAS_INPUTSEL) {
1601 if (*sarg & 0x80)
1602 chip_write_masked(chip,desc->inputreg,desc->inputmute,desc->inputmask);
1603 else
1604 chip_write_masked(chip,desc->inputreg,desc->inputmap[*sarg],desc->inputmask);
1605 }
1606 break;
1607
1608 case AUDC_SET_RADIO: 1619 case AUDC_SET_RADIO:
1609 chip->radio = 1; 1620 chip->radio = 1;
1610 chip->watch_stereo = 0; 1621 chip->watch_stereo = 0;
@@ -1668,6 +1679,48 @@ static int chip_command(struct i2c_client *client,
1668 break; 1679 break;
1669 } 1680 }
1670 1681
1682 case VIDIOC_S_CTRL:
1683 return tvaudio_set_ctrl(chip, arg);
1684
1685 case VIDIOC_INT_G_AUDIO_ROUTING:
1686 {
1687 struct v4l2_routing *rt = arg;
1688
1689 rt->input = chip->input;
1690 rt->output = 0;
1691 break;
1692 }
1693
1694 case VIDIOC_INT_S_AUDIO_ROUTING:
1695 {
1696 struct v4l2_routing *rt = arg;
1697
1698 if (!(desc->flags & CHIP_HAS_INPUTSEL) || rt->input >= 4)
1699 return -EINVAL;
1700 /* There are four inputs: tuner, radio, extern and intern. */
1701 chip->input = rt->input;
1702 if (chip->muted)
1703 break;
1704 chip_write_masked(chip, desc->inputreg,
1705 desc->inputmap[chip->input], desc->inputmask);
1706 break;
1707 }
1708
1709 case VIDIOC_S_AUDIO:
1710 {
1711 struct v4l2_audio *sarg = arg;
1712
1713 if (!(desc->flags & CHIP_HAS_INPUTSEL) || sarg->index >= 4)
1714 return -EINVAL;
1715 /* There are four inputs: tuner, radio, extern and intern. */
1716 chip->input = sarg->index;
1717 if (chip->muted)
1718 break;
1719 chip_write_masked(chip, desc->inputreg,
1720 desc->inputmap[chip->input], desc->inputmask);
1721 break;
1722 }
1723
1671 case VIDIOC_S_TUNER: 1724 case VIDIOC_S_TUNER:
1672 { 1725 {
1673 struct v4l2_tuner *vt = arg; 1726 struct v4l2_tuner *vt = arg;
@@ -1680,6 +1733,7 @@ static int chip_command(struct i2c_client *client,
1680 mode = VIDEO_SOUND_MONO; 1733 mode = VIDEO_SOUND_MONO;
1681 break; 1734 break;
1682 case V4L2_TUNER_MODE_STEREO: 1735 case V4L2_TUNER_MODE_STEREO:
1736 case V4L2_TUNER_MODE_LANG1_LANG2:
1683 mode = VIDEO_SOUND_STEREO; 1737 mode = VIDEO_SOUND_STEREO;
1684 break; 1738 break;
1685 case V4L2_TUNER_MODE_LANG1: 1739 case V4L2_TUNER_MODE_LANG1: