diff options
Diffstat (limited to 'drivers/media/video/tvaudio.c')
-rw-r--r-- | drivers/media/video/tvaudio.c | 154 |
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 | ||
139 | static unsigned short normal_i2c[] = { | 140 | static 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 }; |
149 | I2C_CLIENT_INSMOD; | 150 | I2C_CLIENT_INSMOD; |
150 | 151 | ||
@@ -1101,9 +1102,8 @@ static int tda8425_shift12(int val) { return (val >> 12) | 0xf0; } | |||
1101 | static int tda8425_initialize(struct CHIPSTATE *chip) | 1102 | static 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 | ||
1585 | static 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 | ||
1589 | static int chip_command(struct i2c_client *client, | 1610 | static 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: |