Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / media / i2c / tw2804.c
1 /*
2  * Copyright (C) 2005-2006 Micronas USA Inc.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License (Version 2) as
6  * published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software Foundation,
15  * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
16  */
17
18 #include <linux/module.h>
19 #include <linux/init.h>
20 #include <linux/i2c.h>
21 #include <linux/videodev2.h>
22 #include <linux/ioctl.h>
23 #include <linux/slab.h>
24 #include <media/v4l2-subdev.h>
25 #include <media/v4l2-device.h>
26 #include <media/v4l2-ctrls.h>
27
28 #define TW2804_REG_AUTOGAIN             0x02
29 #define TW2804_REG_HUE                  0x0f
30 #define TW2804_REG_SATURATION           0x10
31 #define TW2804_REG_CONTRAST             0x11
32 #define TW2804_REG_BRIGHTNESS           0x12
33 #define TW2804_REG_COLOR_KILLER         0x14
34 #define TW2804_REG_GAIN                 0x3c
35 #define TW2804_REG_CHROMA_GAIN          0x3d
36 #define TW2804_REG_BLUE_BALANCE         0x3e
37 #define TW2804_REG_RED_BALANCE          0x3f
38
39 struct tw2804 {
40         struct v4l2_subdev sd;
41         struct v4l2_ctrl_handler hdl;
42         u8 channel:2;
43         u8 input:1;
44         int norm;
45 };
46
47 static const u8 global_registers[] = {
48         0x39, 0x00,
49         0x3a, 0xff,
50         0x3b, 0x84,
51         0x3c, 0x80,
52         0x3d, 0x80,
53         0x3e, 0x82,
54         0x3f, 0x82,
55         0x78, 0x00,
56         0xff, 0xff, /* Terminator (reg 0xff does not exist) */
57 };
58
59 static const u8 channel_registers[] = {
60         0x01, 0xc4,
61         0x02, 0xa5,
62         0x03, 0x20,
63         0x04, 0xd0,
64         0x05, 0x20,
65         0x06, 0xd0,
66         0x07, 0x88,
67         0x08, 0x20,
68         0x09, 0x07,
69         0x0a, 0xf0,
70         0x0b, 0x07,
71         0x0c, 0xf0,
72         0x0d, 0x40,
73         0x0e, 0xd2,
74         0x0f, 0x80,
75         0x10, 0x80,
76         0x11, 0x80,
77         0x12, 0x80,
78         0x13, 0x1f,
79         0x14, 0x00,
80         0x15, 0x00,
81         0x16, 0x00,
82         0x17, 0x00,
83         0x18, 0xff,
84         0x19, 0xff,
85         0x1a, 0xff,
86         0x1b, 0xff,
87         0x1c, 0xff,
88         0x1d, 0xff,
89         0x1e, 0xff,
90         0x1f, 0xff,
91         0x20, 0x07,
92         0x21, 0x07,
93         0x22, 0x00,
94         0x23, 0x91,
95         0x24, 0x51,
96         0x25, 0x03,
97         0x26, 0x00,
98         0x27, 0x00,
99         0x28, 0x00,
100         0x29, 0x00,
101         0x2a, 0x00,
102         0x2b, 0x00,
103         0x2c, 0x00,
104         0x2d, 0x00,
105         0x2e, 0x00,
106         0x2f, 0x00,
107         0x30, 0x00,
108         0x31, 0x00,
109         0x32, 0x00,
110         0x33, 0x00,
111         0x34, 0x00,
112         0x35, 0x00,
113         0x36, 0x00,
114         0x37, 0x00,
115         0xff, 0xff, /* Terminator (reg 0xff does not exist) */
116 };
117
118 static int write_reg(struct i2c_client *client, u8 reg, u8 value, u8 channel)
119 {
120         return i2c_smbus_write_byte_data(client, reg | (channel << 6), value);
121 }
122
123 static int write_regs(struct i2c_client *client, const u8 *regs, u8 channel)
124 {
125         int ret;
126         int i;
127
128         for (i = 0; regs[i] != 0xff; i += 2) {
129                 ret = i2c_smbus_write_byte_data(client,
130                                 regs[i] | (channel << 6), regs[i + 1]);
131                 if (ret < 0)
132                         return ret;
133         }
134         return 0;
135 }
136
137 static int read_reg(struct i2c_client *client, u8 reg, u8 channel)
138 {
139         return i2c_smbus_read_byte_data(client, (reg) | (channel << 6));
140 }
141
142 static inline struct tw2804 *to_state(struct v4l2_subdev *sd)
143 {
144         return container_of(sd, struct tw2804, sd);
145 }
146
147 static inline struct tw2804 *to_state_from_ctrl(struct v4l2_ctrl *ctrl)
148 {
149         return container_of(ctrl->handler, struct tw2804, hdl);
150 }
151
152 static int tw2804_log_status(struct v4l2_subdev *sd)
153 {
154         struct tw2804 *state = to_state(sd);
155
156         v4l2_info(sd, "Standard: %s\n",
157                         state->norm & V4L2_STD_525_60 ? "60 Hz" : "50 Hz");
158         v4l2_info(sd, "Channel: %d\n", state->channel);
159         v4l2_info(sd, "Input: %d\n", state->input);
160         return v4l2_ctrl_subdev_log_status(sd);
161 }
162
163 /*
164  * These volatile controls are needed because all four channels share
165  * these controls. So a change made to them through one channel would
166  * require another channel to be updated.
167  *
168  * Normally this would have been done in a different way, but since the one
169  * board that uses this driver sees this single chip as if it was on four
170  * different i2c adapters (each adapter belonging to a separate instance of
171  * the same USB driver) there is no reliable method that I have found to let
172  * the instances know about each other.
173  *
174  * So implementing these global registers as volatile is the best we can do.
175  */
176 static int tw2804_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
177 {
178         struct tw2804 *state = to_state_from_ctrl(ctrl);
179         struct i2c_client *client = v4l2_get_subdevdata(&state->sd);
180
181         switch (ctrl->id) {
182         case V4L2_CID_GAIN:
183                 ctrl->val = read_reg(client, TW2804_REG_GAIN, 0);
184                 return 0;
185
186         case V4L2_CID_CHROMA_GAIN:
187                 ctrl->val = read_reg(client, TW2804_REG_CHROMA_GAIN, 0);
188                 return 0;
189
190         case V4L2_CID_BLUE_BALANCE:
191                 ctrl->val = read_reg(client, TW2804_REG_BLUE_BALANCE, 0);
192                 return 0;
193
194         case V4L2_CID_RED_BALANCE:
195                 ctrl->val = read_reg(client, TW2804_REG_RED_BALANCE, 0);
196                 return 0;
197         }
198         return 0;
199 }
200
201 static int tw2804_s_ctrl(struct v4l2_ctrl *ctrl)
202 {
203         struct tw2804 *state = to_state_from_ctrl(ctrl);
204         struct i2c_client *client = v4l2_get_subdevdata(&state->sd);
205         int addr;
206         int reg;
207
208         switch (ctrl->id) {
209         case V4L2_CID_AUTOGAIN:
210                 addr = TW2804_REG_AUTOGAIN;
211                 reg = read_reg(client, addr, state->channel);
212                 if (reg < 0)
213                         return reg;
214                 if (ctrl->val == 0)
215                         reg &= ~(1 << 7);
216                 else
217                         reg |= 1 << 7;
218                 return write_reg(client, addr, reg, state->channel);
219
220         case V4L2_CID_COLOR_KILLER:
221                 addr = TW2804_REG_COLOR_KILLER;
222                 reg = read_reg(client, addr, state->channel);
223                 if (reg < 0)
224                         return reg;
225                 reg = (reg & ~(0x03)) | (ctrl->val == 0 ? 0x02 : 0x03);
226                 return write_reg(client, addr, reg, state->channel);
227
228         case V4L2_CID_GAIN:
229                 return write_reg(client, TW2804_REG_GAIN, ctrl->val, 0);
230
231         case V4L2_CID_CHROMA_GAIN:
232                 return write_reg(client, TW2804_REG_CHROMA_GAIN, ctrl->val, 0);
233
234         case V4L2_CID_BLUE_BALANCE:
235                 return write_reg(client, TW2804_REG_BLUE_BALANCE, ctrl->val, 0);
236
237         case V4L2_CID_RED_BALANCE:
238                 return write_reg(client, TW2804_REG_RED_BALANCE, ctrl->val, 0);
239
240         case V4L2_CID_BRIGHTNESS:
241                 return write_reg(client, TW2804_REG_BRIGHTNESS,
242                                 ctrl->val, state->channel);
243
244         case V4L2_CID_CONTRAST:
245                 return write_reg(client, TW2804_REG_CONTRAST,
246                                 ctrl->val, state->channel);
247
248         case V4L2_CID_SATURATION:
249                 return write_reg(client, TW2804_REG_SATURATION,
250                                 ctrl->val, state->channel);
251
252         case V4L2_CID_HUE:
253                 return write_reg(client, TW2804_REG_HUE,
254                                 ctrl->val, state->channel);
255
256         default:
257                 break;
258         }
259         return -EINVAL;
260 }
261
262 static int tw2804_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
263 {
264         struct tw2804 *dec = to_state(sd);
265         struct i2c_client *client = v4l2_get_subdevdata(sd);
266         bool is_60hz = norm & V4L2_STD_525_60;
267         u8 regs[] = {
268                 0x01, is_60hz ? 0xc4 : 0x84,
269                 0x09, is_60hz ? 0x07 : 0x04,
270                 0x0a, is_60hz ? 0xf0 : 0x20,
271                 0x0b, is_60hz ? 0x07 : 0x04,
272                 0x0c, is_60hz ? 0xf0 : 0x20,
273                 0x0d, is_60hz ? 0x40 : 0x4a,
274                 0x16, is_60hz ? 0x00 : 0x40,
275                 0x17, is_60hz ? 0x00 : 0x40,
276                 0x20, is_60hz ? 0x07 : 0x0f,
277                 0x21, is_60hz ? 0x07 : 0x0f,
278                 0xff, 0xff,
279         };
280
281         write_regs(client, regs, dec->channel);
282         dec->norm = norm;
283         return 0;
284 }
285
286 static int tw2804_s_video_routing(struct v4l2_subdev *sd, u32 input, u32 output,
287         u32 config)
288 {
289         struct tw2804 *dec = to_state(sd);
290         struct i2c_client *client = v4l2_get_subdevdata(sd);
291         int reg;
292
293         if (config && config - 1 != dec->channel) {
294                 if (config > 4) {
295                         dev_err(&client->dev,
296                                 "channel %d is not between 1 and 4!\n", config);
297                         return -EINVAL;
298                 }
299                 dec->channel = config - 1;
300                 dev_dbg(&client->dev, "initializing TW2804 channel %d\n",
301                         dec->channel);
302                 if (dec->channel == 0 &&
303                                 write_regs(client, global_registers, 0) < 0) {
304                         dev_err(&client->dev,
305                                 "error initializing TW2804 global registers\n");
306                         return -EIO;
307                 }
308                 if (write_regs(client, channel_registers, dec->channel) < 0) {
309                         dev_err(&client->dev,
310                                 "error initializing TW2804 channel %d\n",
311                                 dec->channel);
312                         return -EIO;
313                 }
314         }
315
316         if (input > 1)
317                 return -EINVAL;
318
319         if (input == dec->input)
320                 return 0;
321
322         reg = read_reg(client, 0x22, dec->channel);
323
324         if (reg >= 0) {
325                 if (input == 0)
326                         reg &= ~(1 << 2);
327                 else
328                         reg |= 1 << 2;
329                 reg = write_reg(client, 0x22, reg, dec->channel);
330         }
331
332         if (reg >= 0)
333                 dec->input = input;
334         else
335                 return reg;
336         return 0;
337 }
338
339 static const struct v4l2_ctrl_ops tw2804_ctrl_ops = {
340         .g_volatile_ctrl = tw2804_g_volatile_ctrl,
341         .s_ctrl = tw2804_s_ctrl,
342 };
343
344 static const struct v4l2_subdev_video_ops tw2804_video_ops = {
345         .s_std = tw2804_s_std,
346         .s_routing = tw2804_s_video_routing,
347 };
348
349 static const struct v4l2_subdev_core_ops tw2804_core_ops = {
350         .log_status = tw2804_log_status,
351 };
352
353 static const struct v4l2_subdev_ops tw2804_ops = {
354         .core = &tw2804_core_ops,
355         .video = &tw2804_video_ops,
356 };
357
358 static int tw2804_probe(struct i2c_client *client,
359                             const struct i2c_device_id *id)
360 {
361         struct i2c_adapter *adapter = client->adapter;
362         struct tw2804 *state;
363         struct v4l2_subdev *sd;
364         struct v4l2_ctrl *ctrl;
365         int err;
366
367         if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
368                 return -ENODEV;
369
370         state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
371         if (state == NULL)
372                 return -ENOMEM;
373         sd = &state->sd;
374         v4l2_i2c_subdev_init(sd, client, &tw2804_ops);
375         state->channel = -1;
376         state->norm = V4L2_STD_NTSC;
377
378         v4l2_ctrl_handler_init(&state->hdl, 10);
379         v4l2_ctrl_new_std(&state->hdl, &tw2804_ctrl_ops,
380                                 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
381         v4l2_ctrl_new_std(&state->hdl, &tw2804_ctrl_ops,
382                                 V4L2_CID_CONTRAST, 0, 255, 1, 128);
383         v4l2_ctrl_new_std(&state->hdl, &tw2804_ctrl_ops,
384                                 V4L2_CID_SATURATION, 0, 255, 1, 128);
385         v4l2_ctrl_new_std(&state->hdl, &tw2804_ctrl_ops,
386                                 V4L2_CID_HUE, 0, 255, 1, 128);
387         v4l2_ctrl_new_std(&state->hdl, &tw2804_ctrl_ops,
388                                 V4L2_CID_COLOR_KILLER, 0, 1, 1, 0);
389         v4l2_ctrl_new_std(&state->hdl, &tw2804_ctrl_ops,
390                                 V4L2_CID_AUTOGAIN, 0, 1, 1, 0);
391         ctrl = v4l2_ctrl_new_std(&state->hdl, &tw2804_ctrl_ops,
392                                 V4L2_CID_GAIN, 0, 255, 1, 128);
393         if (ctrl)
394                 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
395         ctrl = v4l2_ctrl_new_std(&state->hdl, &tw2804_ctrl_ops,
396                                 V4L2_CID_CHROMA_GAIN, 0, 255, 1, 128);
397         if (ctrl)
398                 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
399         ctrl = v4l2_ctrl_new_std(&state->hdl, &tw2804_ctrl_ops,
400                                 V4L2_CID_BLUE_BALANCE, 0, 255, 1, 122);
401         if (ctrl)
402                 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
403         ctrl = v4l2_ctrl_new_std(&state->hdl, &tw2804_ctrl_ops,
404                                 V4L2_CID_RED_BALANCE, 0, 255, 1, 122);
405         if (ctrl)
406                 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
407         sd->ctrl_handler = &state->hdl;
408         err = state->hdl.error;
409         if (err) {
410                 v4l2_ctrl_handler_free(&state->hdl);
411                 return err;
412         }
413
414         v4l_info(client, "chip found @ 0x%02x (%s)\n",
415                         client->addr << 1, client->adapter->name);
416
417         return 0;
418 }
419
420 static int tw2804_remove(struct i2c_client *client)
421 {
422         struct v4l2_subdev *sd = i2c_get_clientdata(client);
423         struct tw2804 *state = to_state(sd);
424
425         v4l2_device_unregister_subdev(sd);
426         v4l2_ctrl_handler_free(&state->hdl);
427         return 0;
428 }
429
430 static const struct i2c_device_id tw2804_id[] = {
431         { "tw2804", 0 },
432         { }
433 };
434 MODULE_DEVICE_TABLE(i2c, tw2804_id);
435
436 static struct i2c_driver tw2804_driver = {
437         .driver = {
438                 .name   = "tw2804",
439         },
440         .probe          = tw2804_probe,
441         .remove         = tw2804_remove,
442         .id_table       = tw2804_id,
443 };
444
445 module_i2c_driver(tw2804_driver);
446
447 MODULE_LICENSE("GPL v2");
448 MODULE_DESCRIPTION("TW2804/TW2802 V4L2 i2c driver");
449 MODULE_AUTHOR("Micronas USA Inc");