diff options
Diffstat (limited to 'drivers/media/video/tvaudio.c')
-rw-r--r-- | drivers/media/video/tvaudio.c | 67 |
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; } | |||
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)); |
@@ -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 | ||
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,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; |