Commit 340dde81 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab

V4L/DVB: saa7115: fix saa7111a support

When the saa7111 driver was merged into saa7115 several bugs were introduced,
in particular with the saa7111a support as is used in the mxb.c driver.
This patch fixes the saa7111a support. This was tested with the mxb driver.
Signed-off-by: default avatarHans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent cd7d9beb
...@@ -298,7 +298,7 @@ static int mxb_init_done(struct saa7146_dev* dev) ...@@ -298,7 +298,7 @@ static int mxb_init_done(struct saa7146_dev* dev)
/* select tuner-output on saa7111a */ /* select tuner-output on saa7111a */
i = 0; i = 0;
saa7111a_call(mxb, video, s_routing, SAA7115_COMPOSITE0, saa7111a_call(mxb, video, s_routing, SAA7115_COMPOSITE0,
SAA7111_FMT_CCIR | SAA7111_VBI_BYPASS, 0); SAA7111_FMT_CCIR, 0);
/* select a tuner type */ /* select a tuner type */
tun_setup.mode_mask = T_ANALOG_TV; tun_setup.mode_mask = T_ANALOG_TV;
...@@ -522,8 +522,8 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int input) ...@@ -522,8 +522,8 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
return err; return err;
/* switch video in saa7111a */ /* switch video in saa7111a */
if (saa7111a_call(mxb, video, s_routing, i, 0, 0)) if (saa7111a_call(mxb, video, s_routing, i, SAA7111_FMT_CCIR, 0))
printk(KERN_ERR "VIDIOC_S_INPUT: could not address saa7111a #1.\n"); printk(KERN_ERR "VIDIOC_S_INPUT: could not address saa7111a.\n");
/* switch the audio-source only if necessary */ /* switch the audio-source only if necessary */
if (0 == mxb->cur_mute) if (0 == mxb->cur_mute)
......
...@@ -104,6 +104,10 @@ static int saa711x_has_reg(const int id, const u8 reg) ...@@ -104,6 +104,10 @@ static int saa711x_has_reg(const int id, const u8 reg)
if (id == V4L2_IDENT_SAA7111) if (id == V4L2_IDENT_SAA7111)
return reg < 0x20 && reg != 0x01 && reg != 0x0f && return reg < 0x20 && reg != 0x01 && reg != 0x0f &&
(reg < 0x13 || reg > 0x19) && reg != 0x1d && reg != 0x1e; (reg < 0x13 || reg > 0x19) && reg != 0x1d && reg != 0x1e;
if (id == V4L2_IDENT_SAA7111A)
return reg < 0x20 && reg != 0x01 && reg != 0x0f &&
reg != 0x14 && reg != 0x18 && reg != 0x19 &&
reg != 0x1d && reg != 0x1e;
/* common for saa7113/4/5/8 */ /* common for saa7113/4/5/8 */
if (unlikely((reg >= 0x3b && reg <= 0x3f) || reg == 0x5c || reg == 0x5f || if (unlikely((reg >= 0x3b && reg <= 0x3f) || reg == 0x5c || reg == 0x5f ||
...@@ -954,8 +958,7 @@ static void saa711x_set_v4lstd(struct v4l2_subdev *sd, v4l2_std_id std) ...@@ -954,8 +958,7 @@ static void saa711x_set_v4lstd(struct v4l2_subdev *sd, v4l2_std_id std)
011 NTSC N (3.58MHz) PAL M (3.58MHz) 011 NTSC N (3.58MHz) PAL M (3.58MHz)
100 reserved NTSC-Japan (3.58MHz) 100 reserved NTSC-Japan (3.58MHz)
*/ */
if (state->ident == V4L2_IDENT_SAA7111 || if (state->ident <= V4L2_IDENT_SAA7113) {
state->ident == V4L2_IDENT_SAA7113) {
u8 reg = saa711x_read(sd, R_0E_CHROMA_CNTL_1) & 0x8f; u8 reg = saa711x_read(sd, R_0E_CHROMA_CNTL_1) & 0x8f;
if (std == V4L2_STD_PAL_M) { if (std == V4L2_STD_PAL_M) {
...@@ -1232,22 +1235,19 @@ static int saa711x_s_routing(struct v4l2_subdev *sd, ...@@ -1232,22 +1235,19 @@ static int saa711x_s_routing(struct v4l2_subdev *sd,
u32 input, u32 output, u32 config) u32 input, u32 output, u32 config)
{ {
struct saa711x_state *state = to_state(sd); struct saa711x_state *state = to_state(sd);
u8 mask = (state->ident == V4L2_IDENT_SAA7111) ? 0xf8 : 0xf0; u8 mask = (state->ident <= V4L2_IDENT_SAA7111A) ? 0xf8 : 0xf0;
v4l2_dbg(1, debug, sd, "decoder set input %d output %d\n", v4l2_dbg(1, debug, sd, "decoder set input %d output %d\n",
input, output); input, output);
/* saa7111/3 does not have these inputs */ /* saa7111/3 does not have these inputs */
if ((state->ident == V4L2_IDENT_SAA7113 || if (state->ident <= V4L2_IDENT_SAA7113 &&
state->ident == V4L2_IDENT_SAA7111) &&
(input == SAA7115_COMPOSITE4 || (input == SAA7115_COMPOSITE4 ||
input == SAA7115_COMPOSITE5)) { input == SAA7115_COMPOSITE5)) {
return -EINVAL; return -EINVAL;
} }
if (input > SAA7115_SVIDEO3) if (input > SAA7115_SVIDEO3)
return -EINVAL; return -EINVAL;
if (output > SAA7115_IPORT_ON)
return -EINVAL;
if (state->input == input && state->output == output) if (state->input == input && state->output == output)
return 0; return 0;
v4l2_dbg(1, debug, sd, "now setting %s input %s output\n", v4l2_dbg(1, debug, sd, "now setting %s input %s output\n",
...@@ -1256,7 +1256,7 @@ static int saa711x_s_routing(struct v4l2_subdev *sd, ...@@ -1256,7 +1256,7 @@ static int saa711x_s_routing(struct v4l2_subdev *sd,
state->input = input; state->input = input;
/* saa7111 has slightly different input numbering */ /* saa7111 has slightly different input numbering */
if (state->ident == V4L2_IDENT_SAA7111) { if (state->ident <= V4L2_IDENT_SAA7111A) {
if (input >= SAA7115_COMPOSITE4) if (input >= SAA7115_COMPOSITE4)
input -= 2; input -= 2;
/* saa7111 specific */ /* saa7111 specific */
...@@ -1292,7 +1292,7 @@ static int saa711x_s_gpio(struct v4l2_subdev *sd, u32 val) ...@@ -1292,7 +1292,7 @@ static int saa711x_s_gpio(struct v4l2_subdev *sd, u32 val)
{ {
struct saa711x_state *state = to_state(sd); struct saa711x_state *state = to_state(sd);
if (state->ident != V4L2_IDENT_SAA7111) if (state->ident > V4L2_IDENT_SAA7111A)
return -EINVAL; return -EINVAL;
saa711x_write(sd, 0x11, (saa711x_read(sd, 0x11) & 0x7f) | saa711x_write(sd, 0x11, (saa711x_read(sd, 0x11) & 0x7f) |
(val ? 0x80 : 0)); (val ? 0x80 : 0));
...@@ -1596,6 +1596,10 @@ static int saa711x_probe(struct i2c_client *client, ...@@ -1596,6 +1596,10 @@ static int saa711x_probe(struct i2c_client *client,
switch (chip_id) { switch (chip_id) {
case '1': case '1':
state->ident = V4L2_IDENT_SAA7111; state->ident = V4L2_IDENT_SAA7111;
if (saa711x_read(sd, R_00_CHIP_VERSION) & 0xf0) {
v4l_info(client, "saa7111a variant found\n");
state->ident = V4L2_IDENT_SAA7111A;
}
break; break;
case '3': case '3':
state->ident = V4L2_IDENT_SAA7113; state->ident = V4L2_IDENT_SAA7113;
...@@ -1612,7 +1616,7 @@ static int saa711x_probe(struct i2c_client *client, ...@@ -1612,7 +1616,7 @@ static int saa711x_probe(struct i2c_client *client,
default: default:
state->ident = V4L2_IDENT_SAA7111; state->ident = V4L2_IDENT_SAA7111;
v4l2_info(sd, "WARNING: Chip is not known - Falling back to saa7111\n"); v4l2_info(sd, "WARNING: Chip is not known - Falling back to saa7111\n");
break;
} }
state->audclk_freq = 48000; state->audclk_freq = 48000;
...@@ -1623,6 +1627,7 @@ static int saa711x_probe(struct i2c_client *client, ...@@ -1623,6 +1627,7 @@ static int saa711x_probe(struct i2c_client *client,
state->crystal_freq = SAA7115_FREQ_24_576_MHZ; state->crystal_freq = SAA7115_FREQ_24_576_MHZ;
switch (state->ident) { switch (state->ident) {
case V4L2_IDENT_SAA7111: case V4L2_IDENT_SAA7111:
case V4L2_IDENT_SAA7111A:
saa711x_writeregs(sd, saa7111_init); saa711x_writeregs(sd, saa7111_init);
break; break;
case V4L2_IDENT_SAA7113: case V4L2_IDENT_SAA7113:
...@@ -1632,7 +1637,7 @@ static int saa711x_probe(struct i2c_client *client, ...@@ -1632,7 +1637,7 @@ static int saa711x_probe(struct i2c_client *client,
state->crystal_freq = SAA7115_FREQ_32_11_MHZ; state->crystal_freq = SAA7115_FREQ_32_11_MHZ;
saa711x_writeregs(sd, saa7115_init_auto_input); saa711x_writeregs(sd, saa7115_init_auto_input);
} }
if (state->ident != V4L2_IDENT_SAA7111) if (state->ident > V4L2_IDENT_SAA7111A)
saa711x_writeregs(sd, saa7115_init_misc); saa711x_writeregs(sd, saa7115_init_misc);
saa711x_set_v4lstd(sd, V4L2_STD_NTSC); saa711x_set_v4lstd(sd, V4L2_STD_NTSC);
......
...@@ -39,6 +39,7 @@ enum { ...@@ -39,6 +39,7 @@ enum {
/* module saa7115: reserved range 101-149 */ /* module saa7115: reserved range 101-149 */
V4L2_IDENT_SAA7111 = 101, V4L2_IDENT_SAA7111 = 101,
V4L2_IDENT_SAA7111A = 102,
V4L2_IDENT_SAA7113 = 103, V4L2_IDENT_SAA7113 = 103,
V4L2_IDENT_SAA7114 = 104, V4L2_IDENT_SAA7114 = 104,
V4L2_IDENT_SAA7115 = 105, V4L2_IDENT_SAA7115 = 105,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment