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.c67
1 files changed, 48 insertions, 19 deletions
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index 4cc0497dcbde..15fd55ff69ca 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -30,7 +30,7 @@
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 <media/i2c-addr.h> 36#include <media/i2c-addr.h>
@@ -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;
@@ -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));
@@ -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 },
@@ -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 {
@@ -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,24 @@ 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_S_AUDIO:
1686 {
1687 struct v4l2_audio *sarg = arg;
1688
1689 if (!(desc->flags & CHIP_HAS_INPUTSEL) || sarg->index >= 4)
1690 return -EINVAL;
1691 /* There are four inputs: tuner, radio, extern and intern. */
1692 chip->input = sarg->index;
1693 if (chip->muted)
1694 break;
1695 chip_write_masked(chip, desc->inputreg,
1696 desc->inputmap[chip->input], desc->inputmask);
1697 break;
1698 }
1699
1671 case VIDIOC_S_TUNER: 1700 case VIDIOC_S_TUNER:
1672 { 1701 {
1673 struct v4l2_tuner *vt = arg; 1702 struct v4l2_tuner *vt = arg;