V4L/DVB (10720): bt819: that delay include is needed after all.
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / media / video / bt856.c
CommitLineData
d56410e0 1/*
1da177e4
LT
2 * bt856 - BT856A Digital Video Encoder (Rockwell Part)
3 *
4 * Copyright (C) 1999 Mike Bernson <mike@mlb.org>
5 * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
6 *
7 * Modifications for LML33/DC10plus unified driver
8 * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
9 *
10 * This code was modify/ported from the saa7111 driver written
11 * by Dave Perks.
12 *
13 * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
14 * - moved over to linux>=2.4.x i2c protocol (9/9/2002)
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 */
30
31#include <linux/module.h>
18f3fa1e 32#include <linux/types.h>
a8c26dfe 33#include <linux/ioctl.h>
18f3fa1e 34#include <asm/uaccess.h>
a8c26dfe
HV
35#include <linux/i2c.h>
36#include <linux/i2c-id.h>
1da177e4 37#include <linux/videodev.h>
a8c26dfe
HV
38#include <linux/video_encoder.h>
39#include <media/v4l2-common.h>
40#include <media/v4l2-i2c-drv-legacy.h>
1da177e4
LT
41
42MODULE_DESCRIPTION("Brooktree-856A video encoder driver");
43MODULE_AUTHOR("Mike Bernson & Dave Perks");
44MODULE_LICENSE("GPL");
45
ff699e6b 46static int debug;
1da177e4
LT
47module_param(debug, int, 0);
48MODULE_PARM_DESC(debug, "Debug level (0-1)");
49
1da177e4
LT
50/* ----------------------------------------------------------------------- */
51
187565c4
HV
52#define BT856_REG_OFFSET 0xDA
53#define BT856_NR_REG 6
1da177e4
LT
54
55struct bt856 {
f49a5eae 56 unsigned char reg[BT856_NR_REG];
1da177e4 57
107063c6 58 v4l2_std_id norm;
1da177e4
LT
59};
60
1da177e4
LT
61/* ----------------------------------------------------------------------- */
62
a8c26dfe 63static inline int bt856_write(struct i2c_client *client, u8 reg, u8 value)
1da177e4
LT
64{
65 struct bt856 *encoder = i2c_get_clientdata(client);
66
187565c4 67 encoder->reg[reg - BT856_REG_OFFSET] = value;
1da177e4
LT
68 return i2c_smbus_write_byte_data(client, reg, value);
69}
70
a8c26dfe 71static inline int bt856_setbit(struct i2c_client *client, u8 reg, u8 bit, u8 value)
1da177e4
LT
72{
73 struct bt856 *encoder = i2c_get_clientdata(client);
74
75 return bt856_write(client, reg,
a8c26dfe
HV
76 (encoder->reg[reg - BT856_REG_OFFSET] & ~(1 << bit)) |
77 (value ? (1 << bit) : 0));
1da177e4
LT
78}
79
a8c26dfe 80static void bt856_dump(struct i2c_client *client)
1da177e4
LT
81{
82 int i;
83 struct bt856 *encoder = i2c_get_clientdata(client);
84
a8c26dfe 85 v4l_info(client, "register dump:\n");
f49a5eae 86 for (i = 0; i < BT856_NR_REG; i += 2)
a8c26dfe
HV
87 printk(KERN_CONT " %02x", encoder->reg[i]);
88 printk(KERN_CONT "\n");
1da177e4
LT
89}
90
91/* ----------------------------------------------------------------------- */
92
a8c26dfe 93static int bt856_command(struct i2c_client *client, unsigned cmd, void *arg)
1da177e4
LT
94{
95 struct bt856 *encoder = i2c_get_clientdata(client);
96
97 switch (cmd) {
107063c6 98 case VIDIOC_INT_INIT:
1da177e4 99 /* This is just for testing!!! */
a8c26dfe 100 v4l_dbg(1, debug, client, "init\n");
1da177e4
LT
101 bt856_write(client, 0xdc, 0x18);
102 bt856_write(client, 0xda, 0);
103 bt856_write(client, 0xde, 0);
104
105 bt856_setbit(client, 0xdc, 3, 1);
106 //bt856_setbit(client, 0xdc, 6, 0);
107 bt856_setbit(client, 0xdc, 4, 1);
108
107063c6 109 if (encoder->norm & V4L2_STD_NTSC)
1da177e4 110 bt856_setbit(client, 0xdc, 2, 0);
107063c6 111 else
1da177e4 112 bt856_setbit(client, 0xdc, 2, 1);
1da177e4
LT
113
114 bt856_setbit(client, 0xdc, 1, 1);
115 bt856_setbit(client, 0xde, 4, 0);
116 bt856_setbit(client, 0xde, 3, 1);
117 if (debug != 0)
118 bt856_dump(client);
119 break;
120
107063c6 121 case VIDIOC_INT_S_STD_OUTPUT:
1da177e4 122 {
107063c6 123 v4l2_std_id *iarg = arg;
1da177e4 124
107063c6 125 v4l_dbg(1, debug, client, "set norm %llx\n", *iarg);
1da177e4 126
107063c6 127 if (*iarg & V4L2_STD_NTSC) {
1da177e4 128 bt856_setbit(client, 0xdc, 2, 0);
107063c6 129 } else if (*iarg & V4L2_STD_PAL) {
1da177e4
LT
130 bt856_setbit(client, 0xdc, 2, 1);
131 bt856_setbit(client, 0xda, 0, 0);
132 //bt856_setbit(client, 0xda, 0, 1);
107063c6 133 } else {
1da177e4 134 return -EINVAL;
1da177e4
LT
135 }
136 encoder->norm = *iarg;
137 if (debug != 0)
138 bt856_dump(client);
1da177e4 139 break;
a8c26dfe 140 }
1da177e4 141
107063c6 142 case VIDIOC_INT_S_VIDEO_ROUTING:
1da177e4 143 {
107063c6 144 struct v4l2_routing *route = arg;
1da177e4 145
107063c6 146 v4l_dbg(1, debug, client, "set input %d\n", route->input);
1da177e4
LT
147
148 /* We only have video bus.
107063c6
HV
149 * route->input= 0: input is from bt819
150 * route->input= 1: input is from ZR36060 */
151 switch (route->input) {
1da177e4
LT
152 case 0:
153 bt856_setbit(client, 0xde, 4, 0);
154 bt856_setbit(client, 0xde, 3, 1);
155 bt856_setbit(client, 0xdc, 3, 1);
156 bt856_setbit(client, 0xdc, 6, 0);
157 break;
158 case 1:
159 bt856_setbit(client, 0xde, 4, 0);
160 bt856_setbit(client, 0xde, 3, 1);
161 bt856_setbit(client, 0xdc, 3, 1);
162 bt856_setbit(client, 0xdc, 6, 1);
163 break;
164 case 2: // Color bar
165 bt856_setbit(client, 0xdc, 3, 0);
166 bt856_setbit(client, 0xde, 4, 1);
167 break;
168 default:
169 return -EINVAL;
1da177e4
LT
170 }
171
172 if (debug != 0)
173 bt856_dump(client);
1da177e4 174 break;
a8c26dfe 175 }
1da177e4 176
1da177e4
LT
177 default:
178 return -EINVAL;
179 }
180
181 return 0;
182}
183
184/* ----------------------------------------------------------------------- */
185
a8c26dfe 186static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
1da177e4 187
a8c26dfe 188I2C_CLIENT_INSMOD;
1da177e4 189
a8c26dfe
HV
190static int bt856_probe(struct i2c_client *client,
191 const struct i2c_device_id *id)
1da177e4 192{
1da177e4
LT
193 struct bt856 *encoder;
194
1da177e4 195 /* Check if the adapter supports the needed features */
a8c26dfe
HV
196 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
197 return -ENODEV;
1da177e4 198
a8c26dfe
HV
199 v4l_info(client, "chip found @ 0x%x (%s)\n",
200 client->addr << 1, client->adapter->name);
1da177e4 201
7408187d 202 encoder = kzalloc(sizeof(struct bt856), GFP_KERNEL);
a8c26dfe 203 if (encoder == NULL)
1da177e4 204 return -ENOMEM;
107063c6 205 encoder->norm = V4L2_STD_NTSC;
1da177e4
LT
206 i2c_set_clientdata(client, encoder);
207
1da177e4
LT
208 bt856_write(client, 0xdc, 0x18);
209 bt856_write(client, 0xda, 0);
210 bt856_write(client, 0xde, 0);
211
212 bt856_setbit(client, 0xdc, 3, 1);
213 //bt856_setbit(client, 0xdc, 6, 0);
214 bt856_setbit(client, 0xdc, 4, 1);
215
107063c6 216 if (encoder->norm & V4L2_STD_NTSC)
1da177e4 217 bt856_setbit(client, 0xdc, 2, 0);
107063c6 218 else
1da177e4 219 bt856_setbit(client, 0xdc, 2, 1);
1da177e4
LT
220
221 bt856_setbit(client, 0xdc, 1, 1);
222 bt856_setbit(client, 0xde, 4, 0);
223 bt856_setbit(client, 0xde, 3, 1);
224
225 if (debug != 0)
226 bt856_dump(client);
1da177e4
LT
227 return 0;
228}
229
a8c26dfe 230static int bt856_remove(struct i2c_client *client)
1da177e4 231{
a8c26dfe 232 kfree(i2c_get_clientdata(client));
1da177e4
LT
233 return 0;
234}
235
a8c26dfe
HV
236static const struct i2c_device_id bt856_id[] = {
237 { "bt856", 0 },
238 { }
239};
240MODULE_DEVICE_TABLE(i2c, bt856_id);
1da177e4 241
a8c26dfe
HV
242static struct v4l2_i2c_driver_data v4l2_i2c_data = {
243 .name = "bt856",
244 .driverid = I2C_DRIVERID_BT856,
1da177e4 245 .command = bt856_command,
a8c26dfe
HV
246 .probe = bt856_probe,
247 .remove = bt856_remove,
248 .id_table = bt856_id,
1da177e4 249};