Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.16-rc2 429 lines 9.4 kB view raw
1/* 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> 32#include <linux/init.h> 33#include <linux/delay.h> 34#include <linux/errno.h> 35#include <linux/fs.h> 36#include <linux/kernel.h> 37#include <linux/major.h> 38#include <linux/slab.h> 39#include <linux/mm.h> 40#include <linux/pci.h> 41#include <linux/signal.h> 42#include <asm/io.h> 43#include <asm/pgtable.h> 44#include <asm/page.h> 45#include <linux/sched.h> 46#include <linux/types.h> 47 48#include <linux/videodev.h> 49#include <asm/uaccess.h> 50 51MODULE_DESCRIPTION("Brooktree-856A video encoder driver"); 52MODULE_AUTHOR("Mike Bernson & Dave Perks"); 53MODULE_LICENSE("GPL"); 54 55#include <linux/i2c.h> 56#include <linux/i2c-dev.h> 57 58#define I2C_NAME(s) (s)->name 59 60#include <linux/video_encoder.h> 61 62static int debug = 0; 63module_param(debug, int, 0); 64MODULE_PARM_DESC(debug, "Debug level (0-1)"); 65 66#define dprintk(num, format, args...) \ 67 do { \ 68 if (debug >= num) \ 69 printk(format, ##args); \ 70 } while (0) 71 72/* ----------------------------------------------------------------------- */ 73 74#define REG_OFFSET 0xCE 75 76struct bt856 { 77 unsigned char reg[32]; 78 79 int norm; 80 int enable; 81 int bright; 82 int contrast; 83 int hue; 84 int sat; 85}; 86 87#define I2C_BT856 0x88 88 89/* ----------------------------------------------------------------------- */ 90 91static inline int 92bt856_write (struct i2c_client *client, 93 u8 reg, 94 u8 value) 95{ 96 struct bt856 *encoder = i2c_get_clientdata(client); 97 98 encoder->reg[reg - REG_OFFSET] = value; 99 return i2c_smbus_write_byte_data(client, reg, value); 100} 101 102static inline int 103bt856_setbit (struct i2c_client *client, 104 u8 reg, 105 u8 bit, 106 u8 value) 107{ 108 struct bt856 *encoder = i2c_get_clientdata(client); 109 110 return bt856_write(client, reg, 111 (encoder-> 112 reg[reg - REG_OFFSET] & ~(1 << bit)) | 113 (value ? (1 << bit) : 0)); 114} 115 116static void 117bt856_dump (struct i2c_client *client) 118{ 119 int i; 120 struct bt856 *encoder = i2c_get_clientdata(client); 121 122 printk(KERN_INFO "%s: register dump:", I2C_NAME(client)); 123 for (i = 0xd6; i <= 0xde; i += 2) 124 printk(" %02x", encoder->reg[i - REG_OFFSET]); 125 printk("\n"); 126} 127 128/* ----------------------------------------------------------------------- */ 129 130static int 131bt856_command (struct i2c_client *client, 132 unsigned int cmd, 133 void *arg) 134{ 135 struct bt856 *encoder = i2c_get_clientdata(client); 136 137 switch (cmd) { 138 139 case 0: 140 /* This is just for testing!!! */ 141 dprintk(1, KERN_INFO "bt856: init\n"); 142 bt856_write(client, 0xdc, 0x18); 143 bt856_write(client, 0xda, 0); 144 bt856_write(client, 0xde, 0); 145 146 bt856_setbit(client, 0xdc, 3, 1); 147 //bt856_setbit(client, 0xdc, 6, 0); 148 bt856_setbit(client, 0xdc, 4, 1); 149 150 switch (encoder->norm) { 151 152 case VIDEO_MODE_NTSC: 153 bt856_setbit(client, 0xdc, 2, 0); 154 break; 155 156 case VIDEO_MODE_PAL: 157 bt856_setbit(client, 0xdc, 2, 1); 158 break; 159 } 160 161 bt856_setbit(client, 0xdc, 1, 1); 162 bt856_setbit(client, 0xde, 4, 0); 163 bt856_setbit(client, 0xde, 3, 1); 164 if (debug != 0) 165 bt856_dump(client); 166 break; 167 168 case ENCODER_GET_CAPABILITIES: 169 { 170 struct video_encoder_capability *cap = arg; 171 172 dprintk(1, KERN_INFO "%s: get capabilities\n", 173 I2C_NAME(client)); 174 175 cap->flags = VIDEO_ENCODER_PAL | 176 VIDEO_ENCODER_NTSC | 177 VIDEO_ENCODER_CCIR; 178 cap->inputs = 2; 179 cap->outputs = 1; 180 } 181 break; 182 183 case ENCODER_SET_NORM: 184 { 185 int *iarg = arg; 186 187 dprintk(1, KERN_INFO "%s: set norm %d\n", I2C_NAME(client), 188 *iarg); 189 190 switch (*iarg) { 191 192 case VIDEO_MODE_NTSC: 193 bt856_setbit(client, 0xdc, 2, 0); 194 break; 195 196 case VIDEO_MODE_PAL: 197 bt856_setbit(client, 0xdc, 2, 1); 198 bt856_setbit(client, 0xda, 0, 0); 199 //bt856_setbit(client, 0xda, 0, 1); 200 break; 201 202 default: 203 return -EINVAL; 204 205 } 206 encoder->norm = *iarg; 207 if (debug != 0) 208 bt856_dump(client); 209 } 210 break; 211 212 case ENCODER_SET_INPUT: 213 { 214 int *iarg = arg; 215 216 dprintk(1, KERN_INFO "%s: set input %d\n", I2C_NAME(client), 217 *iarg); 218 219 /* We only have video bus. 220 * iarg = 0: input is from bt819 221 * iarg = 1: input is from ZR36060 */ 222 223 switch (*iarg) { 224 225 case 0: 226 bt856_setbit(client, 0xde, 4, 0); 227 bt856_setbit(client, 0xde, 3, 1); 228 bt856_setbit(client, 0xdc, 3, 1); 229 bt856_setbit(client, 0xdc, 6, 0); 230 break; 231 case 1: 232 bt856_setbit(client, 0xde, 4, 0); 233 bt856_setbit(client, 0xde, 3, 1); 234 bt856_setbit(client, 0xdc, 3, 1); 235 bt856_setbit(client, 0xdc, 6, 1); 236 break; 237 case 2: // Color bar 238 bt856_setbit(client, 0xdc, 3, 0); 239 bt856_setbit(client, 0xde, 4, 1); 240 break; 241 default: 242 return -EINVAL; 243 244 } 245 246 if (debug != 0) 247 bt856_dump(client); 248 } 249 break; 250 251 case ENCODER_SET_OUTPUT: 252 { 253 int *iarg = arg; 254 255 dprintk(1, KERN_INFO "%s: set output %d\n", I2C_NAME(client), 256 *iarg); 257 258 /* not much choice of outputs */ 259 if (*iarg != 0) { 260 return -EINVAL; 261 } 262 } 263 break; 264 265 case ENCODER_ENABLE_OUTPUT: 266 { 267 int *iarg = arg; 268 269 encoder->enable = !!*iarg; 270 271 dprintk(1, KERN_INFO "%s: enable output %d\n", 272 I2C_NAME(client), encoder->enable); 273 } 274 break; 275 276 default: 277 return -EINVAL; 278 } 279 280 return 0; 281} 282 283/* ----------------------------------------------------------------------- */ 284 285/* 286 * Generic i2c probe 287 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' 288 */ 289static unsigned short normal_i2c[] = { I2C_BT856 >> 1, I2C_CLIENT_END }; 290 291static unsigned short ignore = I2C_CLIENT_END; 292 293static struct i2c_client_address_data addr_data = { 294 .normal_i2c = normal_i2c, 295 .probe = &ignore, 296 .ignore = &ignore, 297}; 298 299static struct i2c_driver i2c_driver_bt856; 300 301static int 302bt856_detect_client (struct i2c_adapter *adapter, 303 int address, 304 int kind) 305{ 306 int i; 307 struct i2c_client *client; 308 struct bt856 *encoder; 309 310 dprintk(1, 311 KERN_INFO 312 "bt856.c: detecting bt856 client on address 0x%x\n", 313 address << 1); 314 315 /* Check if the adapter supports the needed features */ 316 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 317 return 0; 318 319 client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); 320 if (client == 0) 321 return -ENOMEM; 322 client->addr = address; 323 client->adapter = adapter; 324 client->driver = &i2c_driver_bt856; 325 strlcpy(I2C_NAME(client), "bt856", sizeof(I2C_NAME(client))); 326 327 encoder = kzalloc(sizeof(struct bt856), GFP_KERNEL); 328 if (encoder == NULL) { 329 kfree(client); 330 return -ENOMEM; 331 } 332 encoder->norm = VIDEO_MODE_NTSC; 333 encoder->enable = 1; 334 i2c_set_clientdata(client, encoder); 335 336 i = i2c_attach_client(client); 337 if (i) { 338 kfree(client); 339 kfree(encoder); 340 return i; 341 } 342 343 bt856_write(client, 0xdc, 0x18); 344 bt856_write(client, 0xda, 0); 345 bt856_write(client, 0xde, 0); 346 347 bt856_setbit(client, 0xdc, 3, 1); 348 //bt856_setbit(client, 0xdc, 6, 0); 349 bt856_setbit(client, 0xdc, 4, 1); 350 351 switch (encoder->norm) { 352 353 case VIDEO_MODE_NTSC: 354 bt856_setbit(client, 0xdc, 2, 0); 355 break; 356 357 case VIDEO_MODE_PAL: 358 bt856_setbit(client, 0xdc, 2, 1); 359 break; 360 } 361 362 bt856_setbit(client, 0xdc, 1, 1); 363 bt856_setbit(client, 0xde, 4, 0); 364 bt856_setbit(client, 0xde, 3, 1); 365 366 if (debug != 0) 367 bt856_dump(client); 368 369 dprintk(1, KERN_INFO "%s_attach: at address 0x%x\n", I2C_NAME(client), 370 client->addr << 1); 371 372 return 0; 373} 374 375static int 376bt856_attach_adapter (struct i2c_adapter *adapter) 377{ 378 dprintk(1, 379 KERN_INFO 380 "bt856.c: starting probe for adapter %s (0x%x)\n", 381 I2C_NAME(adapter), adapter->id); 382 return i2c_probe(adapter, &addr_data, &bt856_detect_client); 383} 384 385static int 386bt856_detach_client (struct i2c_client *client) 387{ 388 struct bt856 *encoder = i2c_get_clientdata(client); 389 int err; 390 391 err = i2c_detach_client(client); 392 if (err) { 393 return err; 394 } 395 396 kfree(encoder); 397 kfree(client); 398 399 return 0; 400} 401 402/* ----------------------------------------------------------------------- */ 403 404static struct i2c_driver i2c_driver_bt856 = { 405 .driver = { 406 .name = "bt856", 407 }, 408 409 .id = I2C_DRIVERID_BT856, 410 411 .attach_adapter = bt856_attach_adapter, 412 .detach_client = bt856_detach_client, 413 .command = bt856_command, 414}; 415 416static int __init 417bt856_init (void) 418{ 419 return i2c_add_driver(&i2c_driver_bt856); 420} 421 422static void __exit 423bt856_exit (void) 424{ 425 i2c_del_driver(&i2c_driver_bt856); 426} 427 428module_init(bt856_init); 429module_exit(bt856_exit);