Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
bt866.c
Go to the documentation of this file.
1 /*
2  bt866 - BT866 Digital Video Encoder (Rockwell Part)
3 
4  Copyright (C) 1999 Mike Bernson <[email protected]>
5  Copyright (C) 1998 Dave Perks <[email protected]>
6 
7  Modifications for LML33/DC10plus unified driver
8  Copyright (C) 2000 Serguei Miridonov <[email protected]>
9 
10  This code was modify/ported from the saa7111 driver written
11  by Dave Perks.
12 
13  This code was adapted for the bt866 by Christer Weinigel and ported
14  to 2.6 by Martin Samuelsson.
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>
32 #include <linux/types.h>
33 #include <linux/slab.h>
34 #include <linux/ioctl.h>
35 #include <asm/uaccess.h>
36 #include <linux/i2c.h>
37 #include <linux/videodev2.h>
38 #include <media/v4l2-device.h>
39 #include <media/v4l2-chip-ident.h>
40 
41 MODULE_DESCRIPTION("Brooktree-866 video encoder driver");
42 MODULE_AUTHOR("Mike Bernson & Dave Perks");
43 MODULE_LICENSE("GPL");
44 
45 static int debug;
46 module_param(debug, int, 0);
47 MODULE_PARM_DESC(debug, "Debug level (0-1)");
48 
49 
50 /* ----------------------------------------------------------------------- */
51 
52 struct bt866 {
53  struct v4l2_subdev sd;
54  u8 reg[256];
55 };
56 
57 static inline struct bt866 *to_bt866(struct v4l2_subdev *sd)
58 {
59  return container_of(sd, struct bt866, sd);
60 }
61 
62 static int bt866_write(struct bt866 *encoder, u8 subaddr, u8 data)
63 {
64  struct i2c_client *client = v4l2_get_subdevdata(&encoder->sd);
65  u8 buffer[2];
66  int err;
67 
68  buffer[0] = subaddr;
69  buffer[1] = data;
70 
71  encoder->reg[subaddr] = data;
72 
73  v4l_dbg(1, debug, client, "write 0x%02x = 0x%02x\n", subaddr, data);
74 
75  for (err = 0; err < 3;) {
76  if (i2c_master_send(client, buffer, 2) == 2)
77  break;
78  err++;
79  v4l_warn(client, "error #%d writing to 0x%02x\n",
80  err, subaddr);
82  }
83  if (err == 3) {
84  v4l_warn(client, "giving up\n");
85  return -1;
86  }
87 
88  return 0;
89 }
90 
91 static int bt866_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
92 {
93  v4l2_dbg(1, debug, sd, "set norm %llx\n", (unsigned long long)std);
94 
95  /* Only PAL supported by this driver at the moment! */
96  if (!(std & V4L2_STD_NTSC))
97  return -EINVAL;
98  return 0;
99 }
100 
101 static int bt866_s_routing(struct v4l2_subdev *sd,
102  u32 input, u32 output, u32 config)
103 {
104  static const __u8 init[] = {
105  0xc8, 0xcc, /* CRSCALE */
106  0xca, 0x91, /* CBSCALE */
107  0xcc, 0x24, /* YC16 | OSDNUM */
108  0xda, 0x00, /* */
109  0xdc, 0x24, /* SETMODE | PAL */
110  0xde, 0x02, /* EACTIVE */
111 
112  /* overlay colors */
113  0x70, 0xEB, 0x90, 0x80, 0xB0, 0x80, /* white */
114  0x72, 0xA2, 0x92, 0x8E, 0xB2, 0x2C, /* yellow */
115  0x74, 0x83, 0x94, 0x2C, 0xB4, 0x9C, /* cyan */
116  0x76, 0x70, 0x96, 0x3A, 0xB6, 0x48, /* green */
117  0x78, 0x54, 0x98, 0xC6, 0xB8, 0xB8, /* magenta */
118  0x7A, 0x41, 0x9A, 0xD4, 0xBA, 0x64, /* red */
119  0x7C, 0x23, 0x9C, 0x72, 0xBC, 0xD4, /* blue */
120  0x7E, 0x10, 0x9E, 0x80, 0xBE, 0x80, /* black */
121 
122  0x60, 0xEB, 0x80, 0x80, 0xc0, 0x80, /* white */
123  0x62, 0xA2, 0x82, 0x8E, 0xc2, 0x2C, /* yellow */
124  0x64, 0x83, 0x84, 0x2C, 0xc4, 0x9C, /* cyan */
125  0x66, 0x70, 0x86, 0x3A, 0xc6, 0x48, /* green */
126  0x68, 0x54, 0x88, 0xC6, 0xc8, 0xB8, /* magenta */
127  0x6A, 0x41, 0x8A, 0xD4, 0xcA, 0x64, /* red */
128  0x6C, 0x23, 0x8C, 0x72, 0xcC, 0xD4, /* blue */
129  0x6E, 0x10, 0x8E, 0x80, 0xcE, 0x80, /* black */
130  };
131  struct bt866 *encoder = to_bt866(sd);
132  u8 val;
133  int i;
134 
135  for (i = 0; i < ARRAY_SIZE(init) / 2; i += 2)
136  bt866_write(encoder, init[i], init[i+1]);
137 
138  val = encoder->reg[0xdc];
139 
140  if (input == 0)
141  val |= 0x40; /* CBSWAP */
142  else
143  val &= ~0x40; /* !CBSWAP */
144 
145  bt866_write(encoder, 0xdc, val);
146 
147  val = encoder->reg[0xcc];
148  if (input == 2)
149  val |= 0x01; /* OSDBAR */
150  else
151  val &= ~0x01; /* !OSDBAR */
152  bt866_write(encoder, 0xcc, val);
153 
154  v4l2_dbg(1, debug, sd, "set input %d\n", input);
155 
156  switch (input) {
157  case 0:
158  case 1:
159  case 2:
160  break;
161  default:
162  return -EINVAL;
163  }
164  return 0;
165 }
166 
167 #if 0
168 /* Code to setup square pixels, might be of some use in the future,
169  but is currently unused. */
170  val = encoder->reg[0xdc];
171  if (*iarg)
172  val |= 1; /* SQUARE */
173  else
174  val &= ~1; /* !SQUARE */
175  bt866_write(client, 0xdc, val);
176 #endif
177 
178 static int bt866_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
179 {
180  struct i2c_client *client = v4l2_get_subdevdata(sd);
181 
182  return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_BT866, 0);
183 }
184 
185 /* ----------------------------------------------------------------------- */
186 
187 static const struct v4l2_subdev_core_ops bt866_core_ops = {
188  .g_chip_ident = bt866_g_chip_ident,
189 };
190 
191 static const struct v4l2_subdev_video_ops bt866_video_ops = {
192  .s_std_output = bt866_s_std_output,
193  .s_routing = bt866_s_routing,
194 };
195 
196 static const struct v4l2_subdev_ops bt866_ops = {
197  .core = &bt866_core_ops,
198  .video = &bt866_video_ops,
199 };
200 
201 static int bt866_probe(struct i2c_client *client,
202  const struct i2c_device_id *id)
203 {
204  struct bt866 *encoder;
205  struct v4l2_subdev *sd;
206 
207  v4l_info(client, "chip found @ 0x%x (%s)\n",
208  client->addr << 1, client->adapter->name);
209 
210  encoder = kzalloc(sizeof(*encoder), GFP_KERNEL);
211  if (encoder == NULL)
212  return -ENOMEM;
213  sd = &encoder->sd;
214  v4l2_i2c_subdev_init(sd, client, &bt866_ops);
215  return 0;
216 }
217 
218 static int bt866_remove(struct i2c_client *client)
219 {
220  struct v4l2_subdev *sd = i2c_get_clientdata(client);
221 
223  kfree(to_bt866(sd));
224  return 0;
225 }
226 
227 static const struct i2c_device_id bt866_id[] = {
228  { "bt866", 0 },
229  { }
230 };
231 MODULE_DEVICE_TABLE(i2c, bt866_id);
232 
233 static struct i2c_driver bt866_driver = {
234  .driver = {
235  .owner = THIS_MODULE,
236  .name = "bt866",
237  },
238  .probe = bt866_probe,
239  .remove = bt866_remove,
240  .id_table = bt866_id,
241 };
242 
243 module_i2c_driver(bt866_driver);