Linux 3.11-rc3
[cris-mirror.git] / drivers / media / i2c / ths7303.c
blob0a2dacbd7a6326286cd1750b70ae174150163b63
1 /*
2 * ths7303/53- THS7303/53 Video Amplifier driver
4 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
5 * Copyright 2013 Cisco Systems, Inc. and/or its affiliates.
7 * Author: Chaithrika U S <chaithrika@ti.com>
9 * Contributors:
10 * Hans Verkuil <hans.verkuil@cisco.com>
11 * Lad, Prabhakar <prabhakar.lad@ti.com>
12 * Martin Bugge <marbugge@cisco.com>
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation version 2.
18 * This program is distributed .as is. WITHOUT ANY WARRANTY of any
19 * kind, whether express or implied; without even the implied warranty
20 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
24 #include <linux/i2c.h>
25 #include <linux/module.h>
26 #include <linux/slab.h>
28 #include <media/ths7303.h>
29 #include <media/v4l2-device.h>
31 #define THS7303_CHANNEL_1 1
32 #define THS7303_CHANNEL_2 2
33 #define THS7303_CHANNEL_3 3
35 struct ths7303_state {
36 struct v4l2_subdev sd;
37 const struct ths7303_platform_data *pdata;
38 struct v4l2_bt_timings bt;
39 int std_id;
40 int stream_on;
43 enum ths7303_filter_mode {
44 THS7303_FILTER_MODE_480I_576I,
45 THS7303_FILTER_MODE_480P_576P,
46 THS7303_FILTER_MODE_720P_1080I,
47 THS7303_FILTER_MODE_1080P,
48 THS7303_FILTER_MODE_DISABLE
51 MODULE_DESCRIPTION("TI THS7303 video amplifier driver");
52 MODULE_AUTHOR("Chaithrika U S");
53 MODULE_LICENSE("GPL");
55 static int debug;
56 module_param(debug, int, 0644);
57 MODULE_PARM_DESC(debug, "Debug level 0-1");
59 static inline struct ths7303_state *to_state(struct v4l2_subdev *sd)
61 return container_of(sd, struct ths7303_state, sd);
64 static int ths7303_read(struct v4l2_subdev *sd, u8 reg)
66 struct i2c_client *client = v4l2_get_subdevdata(sd);
68 return i2c_smbus_read_byte_data(client, reg);
71 static int ths7303_write(struct v4l2_subdev *sd, u8 reg, u8 val)
73 struct i2c_client *client = v4l2_get_subdevdata(sd);
74 int ret;
75 int i;
77 for (i = 0; i < 3; i++) {
78 ret = i2c_smbus_write_byte_data(client, reg, val);
79 if (ret == 0)
80 return 0;
82 return ret;
85 /* following function is used to set ths7303 */
86 int ths7303_setval(struct v4l2_subdev *sd, enum ths7303_filter_mode mode)
88 struct i2c_client *client = v4l2_get_subdevdata(sd);
89 struct ths7303_state *state = to_state(sd);
90 const struct ths7303_platform_data *pdata = state->pdata;
91 u8 val, sel = 0;
92 int err, disable = 0;
94 if (!client)
95 return -EINVAL;
97 switch (mode) {
98 case THS7303_FILTER_MODE_1080P:
99 sel = 0x3; /*1080p and SXGA/UXGA */
100 break;
101 case THS7303_FILTER_MODE_720P_1080I:
102 sel = 0x2; /*720p, 1080i and SVGA/XGA */
103 break;
104 case THS7303_FILTER_MODE_480P_576P:
105 sel = 0x1; /* EDTV 480p/576p and VGA */
106 break;
107 case THS7303_FILTER_MODE_480I_576I:
108 sel = 0x0; /* SDTV, S-Video, 480i/576i */
109 break;
110 default:
111 /* disable all channels */
112 disable = 1;
115 val = (sel << 6) | (sel << 3);
116 if (!disable)
117 val |= (pdata->ch_1 & 0x27);
118 err = ths7303_write(sd, THS7303_CHANNEL_1, val);
119 if (err)
120 goto out;
122 val = (sel << 6) | (sel << 3);
123 if (!disable)
124 val |= (pdata->ch_2 & 0x27);
125 err = ths7303_write(sd, THS7303_CHANNEL_2, val);
126 if (err)
127 goto out;
129 val = (sel << 6) | (sel << 3);
130 if (!disable)
131 val |= (pdata->ch_3 & 0x27);
132 err = ths7303_write(sd, THS7303_CHANNEL_3, val);
133 if (err)
134 goto out;
136 return 0;
137 out:
138 pr_info("write byte data failed\n");
139 return err;
142 static int ths7303_s_std_output(struct v4l2_subdev *sd, v4l2_std_id norm)
144 struct ths7303_state *state = to_state(sd);
146 if (norm & (V4L2_STD_ALL & ~V4L2_STD_SECAM)) {
147 state->std_id = 1;
148 state->bt.pixelclock = 0;
149 return ths7303_setval(sd, THS7303_FILTER_MODE_480I_576I);
152 return ths7303_setval(sd, THS7303_FILTER_MODE_DISABLE);
155 static int ths7303_config(struct v4l2_subdev *sd)
157 struct ths7303_state *state = to_state(sd);
158 int res;
160 if (!state->stream_on) {
161 ths7303_write(sd, THS7303_CHANNEL_1,
162 (ths7303_read(sd, THS7303_CHANNEL_1) & 0xf8) |
163 0x00);
164 ths7303_write(sd, THS7303_CHANNEL_2,
165 (ths7303_read(sd, THS7303_CHANNEL_2) & 0xf8) |
166 0x00);
167 ths7303_write(sd, THS7303_CHANNEL_3,
168 (ths7303_read(sd, THS7303_CHANNEL_3) & 0xf8) |
169 0x00);
170 return 0;
173 if (state->bt.pixelclock > 120000000)
174 res = ths7303_setval(sd, THS7303_FILTER_MODE_1080P);
175 else if (state->bt.pixelclock > 70000000)
176 res = ths7303_setval(sd, THS7303_FILTER_MODE_720P_1080I);
177 else if (state->bt.pixelclock > 20000000)
178 res = ths7303_setval(sd, THS7303_FILTER_MODE_480P_576P);
179 else if (state->std_id)
180 res = ths7303_setval(sd, THS7303_FILTER_MODE_480I_576I);
181 else
182 /* disable all channels */
183 res = ths7303_setval(sd, THS7303_FILTER_MODE_DISABLE);
185 return res;
189 static int ths7303_s_stream(struct v4l2_subdev *sd, int enable)
191 struct ths7303_state *state = to_state(sd);
193 state->stream_on = enable;
195 return ths7303_config(sd);
198 /* for setting filter for HD output */
199 static int ths7303_s_dv_timings(struct v4l2_subdev *sd,
200 struct v4l2_dv_timings *dv_timings)
202 struct ths7303_state *state = to_state(sd);
204 if (!dv_timings || dv_timings->type != V4L2_DV_BT_656_1120)
205 return -EINVAL;
207 state->bt = dv_timings->bt;
208 state->std_id = 0;
210 return ths7303_config(sd);
213 static const struct v4l2_subdev_video_ops ths7303_video_ops = {
214 .s_stream = ths7303_s_stream,
215 .s_std_output = ths7303_s_std_output,
216 .s_dv_timings = ths7303_s_dv_timings,
219 #ifdef CONFIG_VIDEO_ADV_DEBUG
221 static int ths7303_g_register(struct v4l2_subdev *sd,
222 struct v4l2_dbg_register *reg)
224 reg->size = 1;
225 reg->val = ths7303_read(sd, reg->reg);
226 return 0;
229 static int ths7303_s_register(struct v4l2_subdev *sd,
230 const struct v4l2_dbg_register *reg)
232 ths7303_write(sd, reg->reg, reg->val);
233 return 0;
235 #endif
237 static const char * const stc_lpf_sel_txt[4] = {
238 "500-kHz Filter",
239 "2.5-MHz Filter",
240 "5-MHz Filter",
241 "5-MHz Filter",
244 static const char * const in_mux_sel_txt[2] = {
245 "Input A Select",
246 "Input B Select",
249 static const char * const lpf_freq_sel_txt[4] = {
250 "9-MHz LPF",
251 "16-MHz LPF",
252 "35-MHz LPF",
253 "Bypass LPF",
256 static const char * const in_bias_sel_dis_cont_txt[8] = {
257 "Disable Channel",
258 "Mute Function - No Output",
259 "DC Bias Select",
260 "DC Bias + 250 mV Offset Select",
261 "AC Bias Select",
262 "Sync Tip Clamp with low bias",
263 "Sync Tip Clamp with mid bias",
264 "Sync Tip Clamp with high bias",
267 static void ths7303_log_channel_status(struct v4l2_subdev *sd, u8 reg)
269 u8 val = ths7303_read(sd, reg);
271 if ((val & 0x7) == 0) {
272 v4l2_info(sd, "Channel %d Off\n", reg);
273 return;
276 v4l2_info(sd, "Channel %d On\n", reg);
277 v4l2_info(sd, " value 0x%x\n", val);
278 v4l2_info(sd, " %s\n", stc_lpf_sel_txt[(val >> 6) & 0x3]);
279 v4l2_info(sd, " %s\n", in_mux_sel_txt[(val >> 5) & 0x1]);
280 v4l2_info(sd, " %s\n", lpf_freq_sel_txt[(val >> 3) & 0x3]);
281 v4l2_info(sd, " %s\n", in_bias_sel_dis_cont_txt[(val >> 0) & 0x7]);
284 static int ths7303_log_status(struct v4l2_subdev *sd)
286 struct ths7303_state *state = to_state(sd);
288 v4l2_info(sd, "stream %s\n", state->stream_on ? "On" : "Off");
290 if (state->bt.pixelclock) {
291 struct v4l2_bt_timings *bt = bt = &state->bt;
292 u32 frame_width, frame_height;
294 frame_width = bt->width + bt->hfrontporch +
295 bt->hsync + bt->hbackporch;
296 frame_height = bt->height + bt->vfrontporch +
297 bt->vsync + bt->vbackporch;
298 v4l2_info(sd,
299 "timings: %dx%d%s%d (%dx%d). Pix freq. = %d Hz. Polarities = 0x%x\n",
300 bt->width, bt->height, bt->interlaced ? "i" : "p",
301 (frame_height * frame_width) > 0 ?
302 (int)bt->pixelclock /
303 (frame_height * frame_width) : 0,
304 frame_width, frame_height,
305 (int)bt->pixelclock, bt->polarities);
306 } else {
307 v4l2_info(sd, "no timings set\n");
310 ths7303_log_channel_status(sd, THS7303_CHANNEL_1);
311 ths7303_log_channel_status(sd, THS7303_CHANNEL_2);
312 ths7303_log_channel_status(sd, THS7303_CHANNEL_3);
314 return 0;
317 static const struct v4l2_subdev_core_ops ths7303_core_ops = {
318 .log_status = ths7303_log_status,
319 #ifdef CONFIG_VIDEO_ADV_DEBUG
320 .g_register = ths7303_g_register,
321 .s_register = ths7303_s_register,
322 #endif
325 static const struct v4l2_subdev_ops ths7303_ops = {
326 .core = &ths7303_core_ops,
327 .video = &ths7303_video_ops,
330 static int ths7303_probe(struct i2c_client *client,
331 const struct i2c_device_id *id)
333 struct ths7303_platform_data *pdata = client->dev.platform_data;
334 struct ths7303_state *state;
335 struct v4l2_subdev *sd;
337 if (pdata == NULL) {
338 dev_err(&client->dev, "No platform data\n");
339 return -EINVAL;
342 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
343 return -ENODEV;
345 v4l_info(client, "chip found @ 0x%x (%s)\n",
346 client->addr << 1, client->adapter->name);
348 state = devm_kzalloc(&client->dev, sizeof(struct ths7303_state),
349 GFP_KERNEL);
350 if (!state)
351 return -ENOMEM;
353 state->pdata = pdata;
354 sd = &state->sd;
355 v4l2_i2c_subdev_init(sd, client, &ths7303_ops);
357 /* set to default 480I_576I filter mode */
358 if (ths7303_setval(sd, THS7303_FILTER_MODE_480I_576I) < 0) {
359 v4l_err(client, "Setting to 480I_576I filter mode failed!\n");
360 return -EINVAL;
363 return 0;
366 static int ths7303_remove(struct i2c_client *client)
368 struct v4l2_subdev *sd = i2c_get_clientdata(client);
370 v4l2_device_unregister_subdev(sd);
372 return 0;
375 static const struct i2c_device_id ths7303_id[] = {
376 {"ths7303", 0},
377 {"ths7353", 0},
381 MODULE_DEVICE_TABLE(i2c, ths7303_id);
383 static struct i2c_driver ths7303_driver = {
384 .driver = {
385 .owner = THIS_MODULE,
386 .name = "ths73x3",
388 .probe = ths7303_probe,
389 .remove = ths7303_remove,
390 .id_table = ths7303_id,
393 module_i2c_driver(ths7303_driver);