diff options
Diffstat (limited to 'drivers/media/i2c/ths7303.c')
-rw-r--r-- | drivers/media/i2c/ths7303.c | 106 |
1 files changed, 90 insertions, 16 deletions
diff --git a/drivers/media/i2c/ths7303.c b/drivers/media/i2c/ths7303.c index e5c0eedebc58..c31cc04fffd2 100644 --- a/drivers/media/i2c/ths7303.c +++ b/drivers/media/i2c/ths7303.c | |||
@@ -28,6 +28,18 @@ | |||
28 | #include <media/v4l2-subdev.h> | 28 | #include <media/v4l2-subdev.h> |
29 | #include <media/v4l2-chip-ident.h> | 29 | #include <media/v4l2-chip-ident.h> |
30 | 30 | ||
31 | #define THS7303_CHANNEL_1 1 | ||
32 | #define THS7303_CHANNEL_2 2 | ||
33 | #define THS7303_CHANNEL_3 3 | ||
34 | |||
35 | enum ths7303_filter_mode { | ||
36 | THS7303_FILTER_MODE_480I_576I, | ||
37 | THS7303_FILTER_MODE_480P_576P, | ||
38 | THS7303_FILTER_MODE_720P_1080I, | ||
39 | THS7303_FILTER_MODE_1080P, | ||
40 | THS7303_FILTER_MODE_DISABLE | ||
41 | }; | ||
42 | |||
31 | MODULE_DESCRIPTION("TI THS7303 video amplifier driver"); | 43 | MODULE_DESCRIPTION("TI THS7303 video amplifier driver"); |
32 | MODULE_AUTHOR("Chaithrika U S"); | 44 | MODULE_AUTHOR("Chaithrika U S"); |
33 | MODULE_LICENSE("GPL"); | 45 | MODULE_LICENSE("GPL"); |
@@ -37,35 +49,96 @@ module_param(debug, int, 0644); | |||
37 | MODULE_PARM_DESC(debug, "Debug level 0-1"); | 49 | MODULE_PARM_DESC(debug, "Debug level 0-1"); |
38 | 50 | ||
39 | /* following function is used to set ths7303 */ | 51 | /* following function is used to set ths7303 */ |
40 | static int ths7303_setvalue(struct v4l2_subdev *sd, v4l2_std_id std) | 52 | int ths7303_setval(struct v4l2_subdev *sd, enum ths7303_filter_mode mode) |
41 | { | 53 | { |
54 | u8 input_bias_chroma = 3; | ||
55 | u8 input_bias_luma = 3; | ||
56 | int disable = 0; | ||
42 | int err = 0; | 57 | int err = 0; |
43 | u8 val; | 58 | u8 val = 0; |
44 | struct i2c_client *client; | 59 | u8 temp; |
45 | 60 | ||
46 | client = v4l2_get_subdevdata(sd); | 61 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
47 | 62 | ||
48 | if (std & (V4L2_STD_ALL & ~V4L2_STD_SECAM)) { | 63 | if (!client) |
49 | val = 0x02; | 64 | return -EINVAL; |
50 | v4l2_dbg(1, debug, sd, "setting value for SDTV format\n"); | 65 | |
51 | } else { | 66 | switch (mode) { |
52 | val = 0x00; | 67 | case THS7303_FILTER_MODE_1080P: |
53 | v4l2_dbg(1, debug, sd, "disabling all channels\n"); | 68 | val = (3 << 6); |
69 | val |= (3 << 3); | ||
70 | break; | ||
71 | case THS7303_FILTER_MODE_720P_1080I: | ||
72 | val = (2 << 6); | ||
73 | val |= (2 << 3); | ||
74 | break; | ||
75 | case THS7303_FILTER_MODE_480P_576P: | ||
76 | val = (1 << 6); | ||
77 | val |= (1 << 3); | ||
78 | break; | ||
79 | case THS7303_FILTER_MODE_480I_576I: | ||
80 | break; | ||
81 | case THS7303_FILTER_MODE_DISABLE: | ||
82 | pr_info("mode disabled\n"); | ||
83 | /* disable all channels */ | ||
84 | disable = 1; | ||
85 | default: | ||
86 | /* disable all channels */ | ||
87 | disable = 1; | ||
54 | } | 88 | } |
89 | /* Setup channel 2 - Luma - Green */ | ||
90 | temp = val; | ||
91 | if (!disable) | ||
92 | val |= input_bias_luma; | ||
93 | err = i2c_smbus_write_byte_data(client, THS7303_CHANNEL_2, val); | ||
94 | if (err) | ||
95 | goto out; | ||
55 | 96 | ||
56 | err |= i2c_smbus_write_byte_data(client, 0x01, val); | 97 | /* setup two chroma channels */ |
57 | err |= i2c_smbus_write_byte_data(client, 0x02, val); | 98 | if (!disable) |
58 | err |= i2c_smbus_write_byte_data(client, 0x03, val); | 99 | temp |= input_bias_chroma; |
59 | 100 | ||
101 | err = i2c_smbus_write_byte_data(client, THS7303_CHANNEL_1, temp); | ||
60 | if (err) | 102 | if (err) |
61 | v4l2_err(sd, "write failed\n"); | 103 | goto out; |
62 | 104 | ||
105 | err = i2c_smbus_write_byte_data(client, THS7303_CHANNEL_3, temp); | ||
106 | if (err) | ||
107 | goto out; | ||
108 | return err; | ||
109 | out: | ||
110 | pr_info("write byte data failed\n"); | ||
63 | return err; | 111 | return err; |
64 | } | 112 | } |
65 | 113 | ||
66 | static int ths7303_s_std_output(struct v4l2_subdev *sd, v4l2_std_id norm) | 114 | static int ths7303_s_std_output(struct v4l2_subdev *sd, v4l2_std_id norm) |
67 | { | 115 | { |
68 | return ths7303_setvalue(sd, norm); | 116 | if (norm & (V4L2_STD_ALL & ~V4L2_STD_SECAM)) |
117 | return ths7303_setval(sd, THS7303_FILTER_MODE_480I_576I); | ||
118 | else | ||
119 | return ths7303_setval(sd, THS7303_FILTER_MODE_DISABLE); | ||
120 | } | ||
121 | |||
122 | /* for setting filter for HD output */ | ||
123 | static int ths7303_s_dv_timings(struct v4l2_subdev *sd, | ||
124 | struct v4l2_dv_timings *dv_timings) | ||
125 | { | ||
126 | u32 height = dv_timings->bt.height; | ||
127 | int interlaced = dv_timings->bt.interlaced; | ||
128 | int res = 0; | ||
129 | |||
130 | if (height == 1080 && !interlaced) | ||
131 | res = ths7303_setval(sd, THS7303_FILTER_MODE_1080P); | ||
132 | else if ((height == 720 && !interlaced) || | ||
133 | (height == 1080 && interlaced)) | ||
134 | res = ths7303_setval(sd, THS7303_FILTER_MODE_720P_1080I); | ||
135 | else if ((height == 480 || height == 576) && !interlaced) | ||
136 | res = ths7303_setval(sd, THS7303_FILTER_MODE_480P_576P); | ||
137 | else | ||
138 | /* disable all channels */ | ||
139 | res = ths7303_setval(sd, THS7303_FILTER_MODE_DISABLE); | ||
140 | |||
141 | return res; | ||
69 | } | 142 | } |
70 | 143 | ||
71 | static int ths7303_g_chip_ident(struct v4l2_subdev *sd, | 144 | static int ths7303_g_chip_ident(struct v4l2_subdev *sd, |
@@ -78,6 +151,7 @@ static int ths7303_g_chip_ident(struct v4l2_subdev *sd, | |||
78 | 151 | ||
79 | static const struct v4l2_subdev_video_ops ths7303_video_ops = { | 152 | static const struct v4l2_subdev_video_ops ths7303_video_ops = { |
80 | .s_std_output = ths7303_s_std_output, | 153 | .s_std_output = ths7303_s_std_output, |
154 | .s_dv_timings = ths7303_s_dv_timings, | ||
81 | }; | 155 | }; |
82 | 156 | ||
83 | static const struct v4l2_subdev_core_ops ths7303_core_ops = { | 157 | static const struct v4l2_subdev_core_ops ths7303_core_ops = { |
@@ -107,7 +181,7 @@ static int ths7303_probe(struct i2c_client *client, | |||
107 | 181 | ||
108 | v4l2_i2c_subdev_init(sd, client, &ths7303_ops); | 182 | v4l2_i2c_subdev_init(sd, client, &ths7303_ops); |
109 | 183 | ||
110 | return ths7303_setvalue(sd, std_id); | 184 | return ths7303_s_std_output(sd, std_id); |
111 | } | 185 | } |
112 | 186 | ||
113 | static int ths7303_remove(struct i2c_client *client) | 187 | static int ths7303_remove(struct i2c_client *client) |