net: qmi_wwan: add Olivetti Olicard 500
[linux/fpc-iii.git] / drivers / media / i2c / ths7303.c
blobed9ae8875348b6abdd226e3026e4b1d6f117c12f
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 static int ths7303_setval(struct v4l2_subdev *sd,
87 enum ths7303_filter_mode mode)
89 struct i2c_client *client = v4l2_get_subdevdata(sd);
90 struct ths7303_state *state = to_state(sd);
91 const struct ths7303_platform_data *pdata = state->pdata;
92 u8 val, sel = 0;
93 int err, disable = 0;
95 if (!client)
96 return -EINVAL;
98 switch (mode) {
99 case THS7303_FILTER_MODE_1080P:
100 sel = 0x3; /*1080p and SXGA/UXGA */
101 break;
102 case THS7303_FILTER_MODE_720P_1080I:
103 sel = 0x2; /*720p, 1080i and SVGA/XGA */
104 break;
105 case THS7303_FILTER_MODE_480P_576P:
106 sel = 0x1; /* EDTV 480p/576p and VGA */
107 break;
108 case THS7303_FILTER_MODE_480I_576I:
109 sel = 0x0; /* SDTV, S-Video, 480i/576i */
110 break;
111 default:
112 /* disable all channels */
113 disable = 1;
116 val = (sel << 6) | (sel << 3);
117 if (!disable)
118 val |= (pdata->ch_1 & 0x27);
119 err = ths7303_write(sd, THS7303_CHANNEL_1, val);
120 if (err)
121 goto out;
123 val = (sel << 6) | (sel << 3);
124 if (!disable)
125 val |= (pdata->ch_2 & 0x27);
126 err = ths7303_write(sd, THS7303_CHANNEL_2, val);
127 if (err)
128 goto out;
130 val = (sel << 6) | (sel << 3);
131 if (!disable)
132 val |= (pdata->ch_3 & 0x27);
133 err = ths7303_write(sd, THS7303_CHANNEL_3, val);
134 if (err)
135 goto out;
137 return 0;
138 out:
139 pr_info("write byte data failed\n");
140 return err;
143 static int ths7303_s_std_output(struct v4l2_subdev *sd, v4l2_std_id norm)
145 struct ths7303_state *state = to_state(sd);
147 if (norm & (V4L2_STD_ALL & ~V4L2_STD_SECAM)) {
148 state->std_id = 1;
149 state->bt.pixelclock = 0;
150 return ths7303_setval(sd, THS7303_FILTER_MODE_480I_576I);
153 return ths7303_setval(sd, THS7303_FILTER_MODE_DISABLE);
156 static int ths7303_config(struct v4l2_subdev *sd)
158 struct ths7303_state *state = to_state(sd);
159 int res;
161 if (!state->stream_on) {
162 ths7303_write(sd, THS7303_CHANNEL_1,
163 (ths7303_read(sd, THS7303_CHANNEL_1) & 0xf8) |
164 0x00);
165 ths7303_write(sd, THS7303_CHANNEL_2,
166 (ths7303_read(sd, THS7303_CHANNEL_2) & 0xf8) |
167 0x00);
168 ths7303_write(sd, THS7303_CHANNEL_3,
169 (ths7303_read(sd, THS7303_CHANNEL_3) & 0xf8) |
170 0x00);
171 return 0;
174 if (state->bt.pixelclock > 120000000)
175 res = ths7303_setval(sd, THS7303_FILTER_MODE_1080P);
176 else if (state->bt.pixelclock > 70000000)
177 res = ths7303_setval(sd, THS7303_FILTER_MODE_720P_1080I);
178 else if (state->bt.pixelclock > 20000000)
179 res = ths7303_setval(sd, THS7303_FILTER_MODE_480P_576P);
180 else if (state->std_id)
181 res = ths7303_setval(sd, THS7303_FILTER_MODE_480I_576I);
182 else
183 /* disable all channels */
184 res = ths7303_setval(sd, THS7303_FILTER_MODE_DISABLE);
186 return res;
190 static int ths7303_s_stream(struct v4l2_subdev *sd, int enable)
192 struct ths7303_state *state = to_state(sd);
194 state->stream_on = enable;
196 return ths7303_config(sd);
199 /* for setting filter for HD output */
200 static int ths7303_s_dv_timings(struct v4l2_subdev *sd,
201 struct v4l2_dv_timings *dv_timings)
203 struct ths7303_state *state = to_state(sd);
205 if (!dv_timings || dv_timings->type != V4L2_DV_BT_656_1120)
206 return -EINVAL;
208 state->bt = dv_timings->bt;
209 state->std_id = 0;
211 return ths7303_config(sd);
214 static const struct v4l2_subdev_video_ops ths7303_video_ops = {
215 .s_stream = ths7303_s_stream,
216 .s_std_output = ths7303_s_std_output,
217 .s_dv_timings = ths7303_s_dv_timings,
220 #ifdef CONFIG_VIDEO_ADV_DEBUG
222 static int ths7303_g_register(struct v4l2_subdev *sd,
223 struct v4l2_dbg_register *reg)
225 reg->size = 1;
226 reg->val = ths7303_read(sd, reg->reg);
227 return 0;
230 static int ths7303_s_register(struct v4l2_subdev *sd,
231 const struct v4l2_dbg_register *reg)
233 ths7303_write(sd, reg->reg, reg->val);
234 return 0;
236 #endif
238 static const char * const stc_lpf_sel_txt[4] = {
239 "500-kHz Filter",
240 "2.5-MHz Filter",
241 "5-MHz Filter",
242 "5-MHz Filter",
245 static const char * const in_mux_sel_txt[2] = {
246 "Input A Select",
247 "Input B Select",
250 static const char * const lpf_freq_sel_txt[4] = {
251 "9-MHz LPF",
252 "16-MHz LPF",
253 "35-MHz LPF",
254 "Bypass LPF",
257 static const char * const in_bias_sel_dis_cont_txt[8] = {
258 "Disable Channel",
259 "Mute Function - No Output",
260 "DC Bias Select",
261 "DC Bias + 250 mV Offset Select",
262 "AC Bias Select",
263 "Sync Tip Clamp with low bias",
264 "Sync Tip Clamp with mid bias",
265 "Sync Tip Clamp with high bias",
268 static void ths7303_log_channel_status(struct v4l2_subdev *sd, u8 reg)
270 u8 val = ths7303_read(sd, reg);
272 if ((val & 0x7) == 0) {
273 v4l2_info(sd, "Channel %d Off\n", reg);
274 return;
277 v4l2_info(sd, "Channel %d On\n", reg);
278 v4l2_info(sd, " value 0x%x\n", val);
279 v4l2_info(sd, " %s\n", stc_lpf_sel_txt[(val >> 6) & 0x3]);
280 v4l2_info(sd, " %s\n", in_mux_sel_txt[(val >> 5) & 0x1]);
281 v4l2_info(sd, " %s\n", lpf_freq_sel_txt[(val >> 3) & 0x3]);
282 v4l2_info(sd, " %s\n", in_bias_sel_dis_cont_txt[(val >> 0) & 0x7]);
285 static int ths7303_log_status(struct v4l2_subdev *sd)
287 struct ths7303_state *state = to_state(sd);
289 v4l2_info(sd, "stream %s\n", state->stream_on ? "On" : "Off");
291 if (state->bt.pixelclock) {
292 struct v4l2_bt_timings *bt = bt = &state->bt;
293 u32 frame_width, frame_height;
295 frame_width = V4L2_DV_BT_FRAME_WIDTH(bt);
296 frame_height = V4L2_DV_BT_FRAME_HEIGHT(bt);
297 v4l2_info(sd,
298 "timings: %dx%d%s%d (%dx%d). Pix freq. = %d Hz. Polarities = 0x%x\n",
299 bt->width, bt->height, bt->interlaced ? "i" : "p",
300 (frame_height * frame_width) > 0 ?
301 (int)bt->pixelclock /
302 (frame_height * frame_width) : 0,
303 frame_width, frame_height,
304 (int)bt->pixelclock, bt->polarities);
305 } else {
306 v4l2_info(sd, "no timings set\n");
309 ths7303_log_channel_status(sd, THS7303_CHANNEL_1);
310 ths7303_log_channel_status(sd, THS7303_CHANNEL_2);
311 ths7303_log_channel_status(sd, THS7303_CHANNEL_3);
313 return 0;
316 static const struct v4l2_subdev_core_ops ths7303_core_ops = {
317 .log_status = ths7303_log_status,
318 #ifdef CONFIG_VIDEO_ADV_DEBUG
319 .g_register = ths7303_g_register,
320 .s_register = ths7303_s_register,
321 #endif
324 static const struct v4l2_subdev_ops ths7303_ops = {
325 .core = &ths7303_core_ops,
326 .video = &ths7303_video_ops,
329 static int ths7303_probe(struct i2c_client *client,
330 const struct i2c_device_id *id)
332 struct ths7303_platform_data *pdata = client->dev.platform_data;
333 struct ths7303_state *state;
334 struct v4l2_subdev *sd;
336 if (pdata == NULL) {
337 dev_err(&client->dev, "No platform data\n");
338 return -EINVAL;
341 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
342 return -ENODEV;
344 v4l_info(client, "chip found @ 0x%x (%s)\n",
345 client->addr << 1, client->adapter->name);
347 state = devm_kzalloc(&client->dev, sizeof(struct ths7303_state),
348 GFP_KERNEL);
349 if (!state)
350 return -ENOMEM;
352 state->pdata = pdata;
353 sd = &state->sd;
354 v4l2_i2c_subdev_init(sd, client, &ths7303_ops);
356 /* set to default 480I_576I filter mode */
357 if (ths7303_setval(sd, THS7303_FILTER_MODE_480I_576I) < 0) {
358 v4l_err(client, "Setting to 480I_576I filter mode failed!\n");
359 return -EINVAL;
362 return 0;
365 static int ths7303_remove(struct i2c_client *client)
367 struct v4l2_subdev *sd = i2c_get_clientdata(client);
369 v4l2_device_unregister_subdev(sd);
371 return 0;
374 static const struct i2c_device_id ths7303_id[] = {
375 {"ths7303", 0},
376 {"ths7353", 0},
380 MODULE_DEVICE_TABLE(i2c, ths7303_id);
382 static struct i2c_driver ths7303_driver = {
383 .driver = {
384 .owner = THIS_MODULE,
385 .name = "ths73x3",
387 .probe = ths7303_probe,
388 .remove = ths7303_remove,
389 .id_table = ths7303_id,
392 module_i2c_driver(ths7303_driver);