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.34 270 lines 7.1 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/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/i2c-id.h> 38#include <linux/videodev2.h> 39#include <media/v4l2-device.h> 40#include <media/v4l2-chip-ident.h> 41#include <media/v4l2-i2c-drv.h> 42 43MODULE_DESCRIPTION("Brooktree-856A video encoder driver"); 44MODULE_AUTHOR("Mike Bernson & Dave Perks"); 45MODULE_LICENSE("GPL"); 46 47static int debug; 48module_param(debug, int, 0); 49MODULE_PARM_DESC(debug, "Debug level (0-1)"); 50 51 52/* ----------------------------------------------------------------------- */ 53 54#define BT856_REG_OFFSET 0xDA 55#define BT856_NR_REG 6 56 57struct bt856 { 58 struct v4l2_subdev sd; 59 unsigned char reg[BT856_NR_REG]; 60 61 v4l2_std_id norm; 62}; 63 64static inline struct bt856 *to_bt856(struct v4l2_subdev *sd) 65{ 66 return container_of(sd, struct bt856, sd); 67} 68 69/* ----------------------------------------------------------------------- */ 70 71static inline int bt856_write(struct bt856 *encoder, u8 reg, u8 value) 72{ 73 struct i2c_client *client = v4l2_get_subdevdata(&encoder->sd); 74 75 encoder->reg[reg - BT856_REG_OFFSET] = value; 76 return i2c_smbus_write_byte_data(client, reg, value); 77} 78 79static inline int bt856_setbit(struct bt856 *encoder, u8 reg, u8 bit, u8 value) 80{ 81 return bt856_write(encoder, reg, 82 (encoder->reg[reg - BT856_REG_OFFSET] & ~(1 << bit)) | 83 (value ? (1 << bit) : 0)); 84} 85 86static void bt856_dump(struct bt856 *encoder) 87{ 88 int i; 89 90 v4l2_info(&encoder->sd, "register dump:\n"); 91 for (i = 0; i < BT856_NR_REG; i += 2) 92 printk(KERN_CONT " %02x", encoder->reg[i]); 93 printk(KERN_CONT "\n"); 94} 95 96/* ----------------------------------------------------------------------- */ 97 98static int bt856_init(struct v4l2_subdev *sd, u32 arg) 99{ 100 struct bt856 *encoder = to_bt856(sd); 101 102 /* This is just for testing!!! */ 103 v4l2_dbg(1, debug, sd, "init\n"); 104 bt856_write(encoder, 0xdc, 0x18); 105 bt856_write(encoder, 0xda, 0); 106 bt856_write(encoder, 0xde, 0); 107 108 bt856_setbit(encoder, 0xdc, 3, 1); 109 /*bt856_setbit(encoder, 0xdc, 6, 0);*/ 110 bt856_setbit(encoder, 0xdc, 4, 1); 111 112 if (encoder->norm & V4L2_STD_NTSC) 113 bt856_setbit(encoder, 0xdc, 2, 0); 114 else 115 bt856_setbit(encoder, 0xdc, 2, 1); 116 117 bt856_setbit(encoder, 0xdc, 1, 1); 118 bt856_setbit(encoder, 0xde, 4, 0); 119 bt856_setbit(encoder, 0xde, 3, 1); 120 if (debug != 0) 121 bt856_dump(encoder); 122 return 0; 123} 124 125static int bt856_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std) 126{ 127 struct bt856 *encoder = to_bt856(sd); 128 129 v4l2_dbg(1, debug, sd, "set norm %llx\n", (unsigned long long)std); 130 131 if (std & V4L2_STD_NTSC) { 132 bt856_setbit(encoder, 0xdc, 2, 0); 133 } else if (std & V4L2_STD_PAL) { 134 bt856_setbit(encoder, 0xdc, 2, 1); 135 bt856_setbit(encoder, 0xda, 0, 0); 136 /*bt856_setbit(encoder, 0xda, 0, 1);*/ 137 } else { 138 return -EINVAL; 139 } 140 encoder->norm = std; 141 if (debug != 0) 142 bt856_dump(encoder); 143 return 0; 144} 145 146static int bt856_s_routing(struct v4l2_subdev *sd, 147 u32 input, u32 output, u32 config) 148{ 149 struct bt856 *encoder = to_bt856(sd); 150 151 v4l2_dbg(1, debug, sd, "set input %d\n", input); 152 153 /* We only have video bus. 154 * input= 0: input is from bt819 155 * input= 1: input is from ZR36060 */ 156 switch (input) { 157 case 0: 158 bt856_setbit(encoder, 0xde, 4, 0); 159 bt856_setbit(encoder, 0xde, 3, 1); 160 bt856_setbit(encoder, 0xdc, 3, 1); 161 bt856_setbit(encoder, 0xdc, 6, 0); 162 break; 163 case 1: 164 bt856_setbit(encoder, 0xde, 4, 0); 165 bt856_setbit(encoder, 0xde, 3, 1); 166 bt856_setbit(encoder, 0xdc, 3, 1); 167 bt856_setbit(encoder, 0xdc, 6, 1); 168 break; 169 case 2: /* Color bar */ 170 bt856_setbit(encoder, 0xdc, 3, 0); 171 bt856_setbit(encoder, 0xde, 4, 1); 172 break; 173 default: 174 return -EINVAL; 175 } 176 177 if (debug != 0) 178 bt856_dump(encoder); 179 return 0; 180} 181 182static int bt856_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) 183{ 184 struct i2c_client *client = v4l2_get_subdevdata(sd); 185 186 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_BT856, 0); 187} 188 189/* ----------------------------------------------------------------------- */ 190 191static const struct v4l2_subdev_core_ops bt856_core_ops = { 192 .g_chip_ident = bt856_g_chip_ident, 193 .init = bt856_init, 194}; 195 196static const struct v4l2_subdev_video_ops bt856_video_ops = { 197 .s_std_output = bt856_s_std_output, 198 .s_routing = bt856_s_routing, 199}; 200 201static const struct v4l2_subdev_ops bt856_ops = { 202 .core = &bt856_core_ops, 203 .video = &bt856_video_ops, 204}; 205 206/* ----------------------------------------------------------------------- */ 207 208static int bt856_probe(struct i2c_client *client, 209 const struct i2c_device_id *id) 210{ 211 struct bt856 *encoder; 212 struct v4l2_subdev *sd; 213 214 /* Check if the adapter supports the needed features */ 215 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 216 return -ENODEV; 217 218 v4l_info(client, "chip found @ 0x%x (%s)\n", 219 client->addr << 1, client->adapter->name); 220 221 encoder = kzalloc(sizeof(struct bt856), GFP_KERNEL); 222 if (encoder == NULL) 223 return -ENOMEM; 224 sd = &encoder->sd; 225 v4l2_i2c_subdev_init(sd, client, &bt856_ops); 226 encoder->norm = V4L2_STD_NTSC; 227 228 bt856_write(encoder, 0xdc, 0x18); 229 bt856_write(encoder, 0xda, 0); 230 bt856_write(encoder, 0xde, 0); 231 232 bt856_setbit(encoder, 0xdc, 3, 1); 233 /*bt856_setbit(encoder, 0xdc, 6, 0);*/ 234 bt856_setbit(encoder, 0xdc, 4, 1); 235 236 if (encoder->norm & V4L2_STD_NTSC) 237 bt856_setbit(encoder, 0xdc, 2, 0); 238 else 239 bt856_setbit(encoder, 0xdc, 2, 1); 240 241 bt856_setbit(encoder, 0xdc, 1, 1); 242 bt856_setbit(encoder, 0xde, 4, 0); 243 bt856_setbit(encoder, 0xde, 3, 1); 244 245 if (debug != 0) 246 bt856_dump(encoder); 247 return 0; 248} 249 250static int bt856_remove(struct i2c_client *client) 251{ 252 struct v4l2_subdev *sd = i2c_get_clientdata(client); 253 254 v4l2_device_unregister_subdev(sd); 255 kfree(to_bt856(sd)); 256 return 0; 257} 258 259static const struct i2c_device_id bt856_id[] = { 260 { "bt856", 0 }, 261 { } 262}; 263MODULE_DEVICE_TABLE(i2c, bt856_id); 264 265static struct v4l2_i2c_driver_data v4l2_i2c_data = { 266 .name = "bt856", 267 .probe = bt856_probe, 268 .remove = bt856_remove, 269 .id_table = bt856_id, 270};