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 { 186 struct bt856 *encoder; 187 struct v4l2_subdev *sd; 188 189 /* Check if the adapter supports the needed features */ 190 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 191 return -ENODEV; 192 193 v4l_info(client, "chip found @ 0x%x (%s)\n", 194 client->addr << 1, client->adapter->name); 195 196 encoder = devm_kzalloc(&client->dev, sizeof(*encoder), GFP_KERNEL); 197 if (encoder == NULL) 198 return -ENOMEM; 199 sd = &encoder->sd; 200 v4l2_i2c_subdev_init(sd, client, &bt856_ops); 201 encoder->norm = V4L2_STD_NTSC; 202 203 bt856_write(encoder, 0xdc, 0x18); 204 bt856_write(encoder, 0xda, 0); 205 bt856_write(encoder, 0xde, 0); 206 207 bt856_setbit(encoder, 0xdc, 3, 1); 208 /*bt856_setbit(encoder, 0xdc, 6, 0);*/ 209 bt856_setbit(encoder, 0xdc, 4, 1); 210 211 if (encoder->norm & V4L2_STD_NTSC) 212 bt856_setbit(encoder, 0xdc, 2, 0); 213 else 214 bt856_setbit(encoder, 0xdc, 2, 1); 215 216 bt856_setbit(encoder, 0xdc, 1, 1); 217 bt856_setbit(encoder, 0xde, 4, 0); 218 bt856_setbit(encoder, 0xde, 3, 1); 219 220 if (debug != 0) 221 bt856_dump(encoder); 222 return 0; 223 } 224 225 static void bt856_remove(struct i2c_client *client) 226 { 227 struct v4l2_subdev *sd = i2c_get_clientdata(client); 228 229 v4l2_device_unregister_subdev(sd); 230 } 231 232 static const struct i2c_device_id bt856_id[] = { 233 { "bt856", 0 }, 234 { } 235 }; 236 MODULE_DEVICE_TABLE(i2c, bt856_id); 237 238 static struct i2c_driver bt856_driver = { 239 .driver = { 240 .name = "bt856", 241 }, 242 .probe = bt856_probe, 243 .remove = bt856_remove, 244 .id_table = bt856_id, 245 }; 246 247 module_i2c_driver(bt856_driver); 248