rt2800: initialize BBP_R104 on proper subroutines
[linux/fpc-iii.git] / drivers / media / i2c / ths7303.c
blobc4339556a2eae8cf09d187172d274c42aee3c1f0
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-chip-ident.h>
30 #include <media/v4l2-device.h>
32 #define THS7303_CHANNEL_1 1
33 #define THS7303_CHANNEL_2 2
34 #define THS7303_CHANNEL_3 3
36 struct ths7303_state {
37 struct v4l2_subdev sd;
38 struct ths7303_platform_data pdata;
39 struct v4l2_bt_timings bt;
40 int std_id;
41 int stream_on;
42 int driver_data;
45 enum ths7303_filter_mode {
46 THS7303_FILTER_MODE_480I_576I,
47 THS7303_FILTER_MODE_480P_576P,
48 THS7303_FILTER_MODE_720P_1080I,
49 THS7303_FILTER_MODE_1080P,
50 THS7303_FILTER_MODE_DISABLE
53 MODULE_DESCRIPTION("TI THS7303 video amplifier driver");
54 MODULE_AUTHOR("Chaithrika U S");
55 MODULE_LICENSE("GPL");
57 static int debug;
58 module_param(debug, int, 0644);
59 MODULE_PARM_DESC(debug, "Debug level 0-1");
61 static inline struct ths7303_state *to_state(struct v4l2_subdev *sd)
63 return container_of(sd, struct ths7303_state, sd);
66 static int ths7303_read(struct v4l2_subdev *sd, u8 reg)
68 struct i2c_client *client = v4l2_get_subdevdata(sd);
70 return i2c_smbus_read_byte_data(client, reg);
73 static int ths7303_write(struct v4l2_subdev *sd, u8 reg, u8 val)
75 struct i2c_client *client = v4l2_get_subdevdata(sd);
76 int ret;
77 int i;
79 for (i = 0; i < 3; i++) {
80 ret = i2c_smbus_write_byte_data(client, reg, val);
81 if (ret == 0)
82 return 0;
84 return ret;
87 /* following function is used to set ths7303 */
88 int ths7303_setval(struct v4l2_subdev *sd, enum ths7303_filter_mode mode)
90 struct i2c_client *client = v4l2_get_subdevdata(sd);
91 struct ths7303_state *state = to_state(sd);
92 struct ths7303_platform_data *pdata = &state->pdata;
93 u8 val, sel = 0;
94 int err, disable = 0;
96 if (!client)
97 return -EINVAL;
99 switch (mode) {
100 case THS7303_FILTER_MODE_1080P:
101 sel = 0x3; /*1080p and SXGA/UXGA */
102 break;
103 case THS7303_FILTER_MODE_720P_1080I:
104 sel = 0x2; /*720p, 1080i and SVGA/XGA */
105 break;
106 case THS7303_FILTER_MODE_480P_576P:
107 sel = 0x1; /* EDTV 480p/576p and VGA */
108 break;
109 case THS7303_FILTER_MODE_480I_576I:
110 sel = 0x0; /* SDTV, S-Video, 480i/576i */
111 break;
112 default:
113 /* disable all channels */
114 disable = 1;
117 val = (sel << 6) | (sel << 3);
118 if (!disable)
119 val |= (pdata->ch_1 & 0x27);
120 err = ths7303_write(sd, THS7303_CHANNEL_1, val);
121 if (err)
122 goto out;
124 val = (sel << 6) | (sel << 3);
125 if (!disable)
126 val |= (pdata->ch_2 & 0x27);
127 err = ths7303_write(sd, THS7303_CHANNEL_2, val);
128 if (err)
129 goto out;
131 val = (sel << 6) | (sel << 3);
132 if (!disable)
133 val |= (pdata->ch_3 & 0x27);
134 err = ths7303_write(sd, THS7303_CHANNEL_3, val);
135 if (err)
136 goto out;
138 return 0;
139 out:
140 pr_info("write byte data failed\n");
141 return err;
144 static int ths7303_s_std_output(struct v4l2_subdev *sd, v4l2_std_id norm)
146 struct ths7303_state *state = to_state(sd);
148 if (norm & (V4L2_STD_ALL & ~V4L2_STD_SECAM)) {
149 state->std_id = 1;
150 state->bt.pixelclock = 0;
151 return ths7303_setval(sd, THS7303_FILTER_MODE_480I_576I);
154 return ths7303_setval(sd, THS7303_FILTER_MODE_DISABLE);
157 static int ths7303_config(struct v4l2_subdev *sd)
159 struct ths7303_state *state = to_state(sd);
160 int res;
162 if (!state->stream_on) {
163 ths7303_write(sd, THS7303_CHANNEL_1,
164 (ths7303_read(sd, THS7303_CHANNEL_1) & 0xf8) |
165 0x00);
166 ths7303_write(sd, THS7303_CHANNEL_2,
167 (ths7303_read(sd, THS7303_CHANNEL_2) & 0xf8) |
168 0x00);
169 ths7303_write(sd, THS7303_CHANNEL_3,
170 (ths7303_read(sd, THS7303_CHANNEL_3) & 0xf8) |
171 0x00);
172 return 0;
175 if (state->bt.pixelclock > 120000000)
176 res = ths7303_setval(sd, THS7303_FILTER_MODE_1080P);
177 else if (state->bt.pixelclock > 70000000)
178 res = ths7303_setval(sd, THS7303_FILTER_MODE_720P_1080I);
179 else if (state->bt.pixelclock > 20000000)
180 res = ths7303_setval(sd, THS7303_FILTER_MODE_480P_576P);
181 else if (state->std_id)
182 res = ths7303_setval(sd, THS7303_FILTER_MODE_480I_576I);
183 else
184 /* disable all channels */
185 res = ths7303_setval(sd, THS7303_FILTER_MODE_DISABLE);
187 return res;
191 static int ths7303_s_stream(struct v4l2_subdev *sd, int enable)
193 struct ths7303_state *state = to_state(sd);
195 state->stream_on = enable;
197 return ths7303_config(sd);
200 /* for setting filter for HD output */
201 static int ths7303_s_dv_timings(struct v4l2_subdev *sd,
202 struct v4l2_dv_timings *dv_timings)
204 struct ths7303_state *state = to_state(sd);
206 if (!dv_timings || dv_timings->type != V4L2_DV_BT_656_1120)
207 return -EINVAL;
209 state->bt = dv_timings->bt;
210 state->std_id = 0;
212 return ths7303_config(sd);
215 static int ths7303_g_chip_ident(struct v4l2_subdev *sd,
216 struct v4l2_dbg_chip_ident *chip)
218 struct i2c_client *client = v4l2_get_subdevdata(sd);
219 struct ths7303_state *state = to_state(sd);
221 return v4l2_chip_ident_i2c_client(client, chip, state->driver_data, 0);
224 static const struct v4l2_subdev_video_ops ths7303_video_ops = {
225 .s_stream = ths7303_s_stream,
226 .s_std_output = ths7303_s_std_output,
227 .s_dv_timings = ths7303_s_dv_timings,
230 #ifdef CONFIG_VIDEO_ADV_DEBUG
232 static int ths7303_g_register(struct v4l2_subdev *sd,
233 struct v4l2_dbg_register *reg)
235 struct i2c_client *client = v4l2_get_subdevdata(sd);
237 if (!v4l2_chip_match_i2c_client(client, &reg->match))
238 return -EINVAL;
239 if (!capable(CAP_SYS_ADMIN))
240 return -EPERM;
242 reg->size = 1;
243 reg->val = ths7303_read(sd, reg->reg);
244 return 0;
247 static int ths7303_s_register(struct v4l2_subdev *sd,
248 const struct v4l2_dbg_register *reg)
250 struct i2c_client *client = v4l2_get_subdevdata(sd);
252 if (!v4l2_chip_match_i2c_client(client, &reg->match))
253 return -EINVAL;
254 if (!capable(CAP_SYS_ADMIN))
255 return -EPERM;
257 ths7303_write(sd, reg->reg, reg->val);
258 return 0;
260 #endif
262 static const char * const stc_lpf_sel_txt[4] = {
263 "500-kHz Filter",
264 "2.5-MHz Filter",
265 "5-MHz Filter",
266 "5-MHz Filter",
269 static const char * const in_mux_sel_txt[2] = {
270 "Input A Select",
271 "Input B Select",
274 static const char * const lpf_freq_sel_txt[4] = {
275 "9-MHz LPF",
276 "16-MHz LPF",
277 "35-MHz LPF",
278 "Bypass LPF",
281 static const char * const in_bias_sel_dis_cont_txt[8] = {
282 "Disable Channel",
283 "Mute Function - No Output",
284 "DC Bias Select",
285 "DC Bias + 250 mV Offset Select",
286 "AC Bias Select",
287 "Sync Tip Clamp with low bias",
288 "Sync Tip Clamp with mid bias",
289 "Sync Tip Clamp with high bias",
292 static void ths7303_log_channel_status(struct v4l2_subdev *sd, u8 reg)
294 u8 val = ths7303_read(sd, reg);
296 if ((val & 0x7) == 0) {
297 v4l2_info(sd, "Channel %d Off\n", reg);
298 return;
301 v4l2_info(sd, "Channel %d On\n", reg);
302 v4l2_info(sd, " value 0x%x\n", val);
303 v4l2_info(sd, " %s\n", stc_lpf_sel_txt[(val >> 6) & 0x3]);
304 v4l2_info(sd, " %s\n", in_mux_sel_txt[(val >> 5) & 0x1]);
305 v4l2_info(sd, " %s\n", lpf_freq_sel_txt[(val >> 3) & 0x3]);
306 v4l2_info(sd, " %s\n", in_bias_sel_dis_cont_txt[(val >> 0) & 0x7]);
309 static int ths7303_log_status(struct v4l2_subdev *sd)
311 struct ths7303_state *state = to_state(sd);
313 v4l2_info(sd, "stream %s\n", state->stream_on ? "On" : "Off");
315 if (state->bt.pixelclock) {
316 struct v4l2_bt_timings *bt = bt = &state->bt;
317 u32 frame_width, frame_height;
319 frame_width = bt->width + bt->hfrontporch +
320 bt->hsync + bt->hbackporch;
321 frame_height = bt->height + bt->vfrontporch +
322 bt->vsync + bt->vbackporch;
323 v4l2_info(sd,
324 "timings: %dx%d%s%d (%dx%d). Pix freq. = %d Hz. Polarities = 0x%x\n",
325 bt->width, bt->height, bt->interlaced ? "i" : "p",
326 (frame_height * frame_width) > 0 ?
327 (int)bt->pixelclock /
328 (frame_height * frame_width) : 0,
329 frame_width, frame_height,
330 (int)bt->pixelclock, bt->polarities);
331 } else {
332 v4l2_info(sd, "no timings set\n");
335 ths7303_log_channel_status(sd, THS7303_CHANNEL_1);
336 ths7303_log_channel_status(sd, THS7303_CHANNEL_2);
337 ths7303_log_channel_status(sd, THS7303_CHANNEL_3);
339 return 0;
342 static const struct v4l2_subdev_core_ops ths7303_core_ops = {
343 .g_chip_ident = ths7303_g_chip_ident,
344 .log_status = ths7303_log_status,
345 #ifdef CONFIG_VIDEO_ADV_DEBUG
346 .g_register = ths7303_g_register,
347 .s_register = ths7303_s_register,
348 #endif
351 static const struct v4l2_subdev_ops ths7303_ops = {
352 .core = &ths7303_core_ops,
353 .video = &ths7303_video_ops,
356 static int ths7303_setup(struct v4l2_subdev *sd)
358 struct ths7303_state *state = to_state(sd);
359 struct ths7303_platform_data *pdata = &state->pdata;
360 int ret;
361 u8 mask;
363 state->stream_on = pdata->init_enable;
365 mask = state->stream_on ? 0xff : 0xf8;
367 ret = ths7303_write(sd, THS7303_CHANNEL_1, pdata->ch_1 & mask);
368 if (ret)
369 return ret;
371 ret = ths7303_write(sd, THS7303_CHANNEL_2, pdata->ch_2 & mask);
372 if (ret)
373 return ret;
375 ret = ths7303_write(sd, THS7303_CHANNEL_3, pdata->ch_3 & mask);
376 if (ret)
377 return ret;
379 return 0;
382 static int ths7303_probe(struct i2c_client *client,
383 const struct i2c_device_id *id)
385 struct ths7303_platform_data *pdata = client->dev.platform_data;
386 struct ths7303_state *state;
387 struct v4l2_subdev *sd;
389 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
390 return -ENODEV;
392 v4l_info(client, "chip found @ 0x%x (%s)\n",
393 client->addr << 1, client->adapter->name);
395 state = devm_kzalloc(&client->dev, sizeof(struct ths7303_state),
396 GFP_KERNEL);
397 if (!state)
398 return -ENOMEM;
400 if (!pdata)
401 v4l_warn(client, "No platform data, using default data!\n");
402 else
403 state->pdata = *pdata;
405 sd = &state->sd;
406 v4l2_i2c_subdev_init(sd, client, &ths7303_ops);
408 /* store the driver data to differntiate the chip */
409 state->driver_data = (int)id->driver_data;
411 if (ths7303_setup(sd) < 0) {
412 v4l_err(client, "init failed\n");
413 return -EIO;
416 return 0;
419 static int ths7303_remove(struct i2c_client *client)
421 struct v4l2_subdev *sd = i2c_get_clientdata(client);
423 v4l2_device_unregister_subdev(sd);
425 return 0;
428 static const struct i2c_device_id ths7303_id[] = {
429 {"ths7303", V4L2_IDENT_THS7303},
430 {"ths7353", V4L2_IDENT_THS7353},
434 MODULE_DEVICE_TABLE(i2c, ths7303_id);
436 static struct i2c_driver ths7303_driver = {
437 .driver = {
438 .owner = THIS_MODULE,
439 .name = "ths73x3",
441 .probe = ths7303_probe,
442 .remove = ths7303_remove,
443 .id_table = ths7303_id,
446 module_i2c_driver(ths7303_driver);