1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * bt856 - BT856A Digital Video Encoder (Rockwell Part) 4 * 5 * Copyright (C) 1999 Mike Bernson <mike@mlb.org> 6 * Copyright (C) 1998 Dave Perks <dperks@ibm.net> 7 * 8 * Modifications for LML33/DC10plus unified driver 9 * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx> 10 * 11 * This code was modify/ported from the saa7111 driver written 12 * by Dave Perks. 13 * 14 * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net> 15 * - moved over to linux>=2.4.x i2c protocol (9/9/2002) 16 */ 17 18 #include <linux/module.h> 19 #include <linux/types.h> 20 #include <linux/slab.h> 21 #include <linux/ioctl.h> 22 #include <linux/uaccess.h> 23 #include <linux/i2c.h> 24 #include <linux/videodev2.h> 25 #include <media/v4l2-device.h> 26 27 MODULE_DESCRIPTION("Brooktree-856A video encoder driver"); 28 MODULE_AUTHOR("Mike Bernson & Dave Perks"); 29 MODULE_LICENSE("GPL"); 30 31 static int debug; 32 module_param(debug, int, 0); 33 MODULE_PARM_DESC(debug, "Debug level (0-1)"); 34 35 36 /* ----------------------------------------------------------------------- */ 37 38 #define BT856_REG_OFFSET 0xDA 39 #define BT856_NR_REG 6 40 41 struct bt856 { 42 struct v4l2_subdev sd; 43 unsigned char reg[BT856_NR_REG]; 44 45 v4l2_std_id norm; 46 }; 47 48 static inline struct bt856 *to_bt856(struct v4l2_subdev *sd) 49 { 50 return container_of(sd, struct bt856, sd); 51 } 52 53 /* ----------------------------------------------------------------------- */ 54 55 static inline int bt856_write(struct bt856 *encoder, u8 reg, u8 value) 56 { 57 struct i2c_client *client = v4l2_get_subdevdata(&encoder->sd); 58 59 encoder->reg[reg - BT856_REG_OFFSET] = value; 60 return i2c_smbus_write_byte_data(client, reg, value); 61 } 62 63 static inline int bt856_setbit(struct bt856 *encoder, u8 reg, u8 bit, u8 value) 64 { 65 return bt856_write(encoder, reg, 66 (encoder->reg[reg - BT856_REG_OFFSET] & ~(1 << bit)) | 67 (value ? (1 << bit) : 0)); 68 } 69 70 static void bt856_dump(struct bt856 *encoder) 71 { 72 int i; 73 74 v4l2_info(&encoder->sd, "register dump:\n"); 75 for (i = 0; i < BT856_NR_REG; i += 2) 76 printk(KERN_CONT " %02x", encoder->reg[i]); 77 printk(KERN_CONT "\n"); 78 } 79 80 /* ----------------------------------------------------------------------- */ 81 82 static int bt856_init(struct v4l2_subdev *sd, u32 arg) 83 { 84 struct bt856 *encoder = to_bt856(sd); 85 86 /* This is just for testing!!! */ 87 v4l2_dbg(1, debug, sd, "init\n"); 88 bt856_write(encoder, 0xdc, 0x18); 89 bt856_write(encoder, 0xda, 0); 90 bt856_write(encoder, 0xde, 0); 91 92 bt856_setbit(encoder, 0xdc, 3, 1); 93 /*bt856_setbit(encoder, 0xdc, 6, 0);*/ 94 bt856_setbit(encoder, 0xdc, 4, 1); 95 96 if (encoder->norm & V4L2_STD_NTSC) 97 bt856_setbit(encoder, 0xdc, 2, 0); 98 else 99 bt856_setbit(encoder, 0xdc, 2, 1); 100 101 bt856_setbit(encoder, 0xdc, 1, 1); 102 bt856_setbit(encoder, 0xde, 4, 0); 103 bt856_setbit(encoder, 0xde, 3, 1); 104 if (debug != 0) 105 bt856_dump(encoder); 106 return 0; 107 } 108 109 static int bt856_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std) 110 { 111 struct bt856 *encoder = to_bt856(sd); 112 113 v4l2_dbg(1, debug, sd, "set norm %llx\n", (unsigned long long)std); 114 115 if (std & V4L2_STD_NTSC) { 116 bt856_setbit(encoder, 0xdc, 2, 0); 117 } else if (std & V4L2_STD_PAL) { 118 bt856_setbit(encoder, 0xdc, 2, 1); 119 bt856_setbit(encoder, 0xda, 0, 0); 120 /*bt856_setbit(encoder, 0xda, 0, 1);*/ 121 } else { 122 return -EINVAL; 123 } 124 encoder->norm = std; 125 if (debug != 0) 126 bt856_dump(encoder); 127 return 0; 128 } 129 130 static int bt856_s_routing(struct v4l2_subdev *sd, 131 u32 input, u32 output, u32 config) 132 { 133 struct bt856 *encoder = to_bt856(sd); 134 135 v4l2_dbg(1, debug, sd, "set input %d\n", input); 136 137 /* We only have video bus. 138 * input= 0: input is from bt819 139 * input= 1: input is from ZR36060 */ 140 switch (input) { 141 case 0: 142 bt856_setbit(encoder, 0xde, 4, 0); 143 bt856_setbit(encoder, 0xde, 3, 1); 144 bt856_setbit(encoder, 0xdc, 3, 1); 145 bt856_setbit(encoder, 0xdc, 6, 0); 146 break; 147 case 1: 148 bt856_setbit(encoder, 0xde, 4, 0); 149 bt856_setbit(encoder, 0xde, 3, 1); 150 bt856_setbit(encoder, 0xdc, 3, 1); 151 bt856_setbit(encoder, 0xdc, 6, 1); 152 break; 153 case 2: /* Color bar */ 154 bt856_setbit(encoder, 0xdc, 3, 0); 155 bt856_setbit(encoder, 0xde, 4, 1); 156 break; 157 default: 158 return -EINVAL; 159 } 160 161 if (debug != 0) 162 bt856_dump(encoder); 163 return 0; 164 } 165 166 /* ----------------------------------------------------------------------- */ 167 168 static const struct v4l2_subdev_core_ops bt856_core_ops = { 169 .init = bt856_init, 170 }; 171 172 static const struct v4l2_subdev_video_ops bt856_video_ops = { 173 .s_std_output = bt856_s_std_output, 174 .s_routing = bt856_s_routing, 175 }; 176 177 static const struct v4l2_subdev_ops bt856_ops = { 178 .core = &bt856_core_ops, 179 .video = &bt856_video_ops, 180 }; 181 182 /* ----------------------------------------------------------------------- */ 183 184 static int bt856_probe(struct i2c_client *client, 185 const struct i2c_device_id *id) 186 { 187 struct bt856 *encoder; 188 struct v4l2_subdev *sd; 189 190 /* Check if the adapter supports the needed features */ 191 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 192 return -ENODEV; 193 194 v4l_info(client, "chip found @ 0x%x (%s)\n", 195 client->addr << 1, client->adapter->name); 196 197 encoder = devm_kzalloc(&client->dev, sizeof(*encoder), GFP_KERNEL); 198 if (encoder == NULL) 199 return -ENOMEM; 200 sd = &encoder->sd; 201 v4l2_i2c_subdev_init(sd, client, &bt856_ops); 202 encoder->norm = V4L2_STD_NTSC; 203 204 bt856_write(encoder, 0xdc, 0x18); 205 bt856_write(encoder, 0xda, 0); 206 bt856_write(encoder, 0xde, 0); 207 208 bt856_setbit(encoder, 0xdc, 3, 1); 209 /*bt856_setbit(encoder, 0xdc, 6, 0);*/ 210 bt856_setbit(encoder, 0xdc, 4, 1); 211 212 if (encoder->norm & V4L2_STD_NTSC) 213 bt856_setbit(encoder, 0xdc, 2, 0); 214 else 215 bt856_setbit(encoder, 0xdc, 2, 1); 216 217 bt856_setbit(encoder, 0xdc, 1, 1); 218 bt856_setbit(encoder, 0xde, 4, 0); 219 bt856_setbit(encoder, 0xde, 3, 1); 220 221 if (debug != 0) 222 bt856_dump(encoder); 223 return 0; 224 } 225 226 static void bt856_remove(struct i2c_client *client) 227 { 228 struct v4l2_subdev *sd = i2c_get_clientdata(client); 229 230 v4l2_device_unregister_subdev(sd); 231 } 232 233 static const struct i2c_device_id bt856_id[] = { 234 { "bt856", 0 }, 235 { } 236 }; 237 MODULE_DEVICE_TABLE(i2c, bt856_id); 238 239 static struct i2c_driver bt856_driver = { 240 .driver = { 241 .name = "bt856", 242 }, 243 .probe = bt856_probe, 244 .remove = bt856_remove, 245 .id_table = bt856_id, 246 }; 247 248 module_i2c_driver(bt856_driver); 249