0001
0002
0003
0004
0005
0006 #include <linux/module.h>
0007 #include <linux/init.h>
0008 #include <linux/i2c.h>
0009 #include <linux/videodev2.h>
0010 #include <media/tuner.h>
0011 #include <media/v4l2-common.h>
0012 #include <media/v4l2-ioctl.h>
0013 #include <media/v4l2-device.h>
0014 #include <linux/slab.h>
0015
0016 MODULE_DESCRIPTION("sony-btf-mpx driver");
0017 MODULE_LICENSE("GPL v2");
0018
0019 static int debug;
0020 module_param(debug, int, 0644);
0021 MODULE_PARM_DESC(debug, "debug level 0=off(default) 1=on");
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 static int force_mpx_mode = -1;
0034 module_param(force_mpx_mode, int, 0644);
0035
0036 struct sony_btf_mpx {
0037 struct v4l2_subdev sd;
0038 int mpxmode;
0039 u32 audmode;
0040 };
0041
0042 static inline struct sony_btf_mpx *to_state(struct v4l2_subdev *sd)
0043 {
0044 return container_of(sd, struct sony_btf_mpx, sd);
0045 }
0046
0047 static int mpx_write(struct i2c_client *client, int dev, int addr, int val)
0048 {
0049 u8 buffer[5];
0050 struct i2c_msg msg;
0051
0052 buffer[0] = dev;
0053 buffer[1] = addr >> 8;
0054 buffer[2] = addr & 0xff;
0055 buffer[3] = val >> 8;
0056 buffer[4] = val & 0xff;
0057 msg.addr = client->addr;
0058 msg.flags = 0;
0059 msg.len = 5;
0060 msg.buf = buffer;
0061 i2c_transfer(client->adapter, &msg, 1);
0062 return 0;
0063 }
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116 static const struct {
0117 enum { AUD_MONO, AUD_A2, AUD_NICAM, AUD_NICAM_L } audio_mode;
0118 u16 modus;
0119 u16 source;
0120 u16 acb;
0121 u16 fm_prescale;
0122 u16 nicam_prescale;
0123 u16 scart_prescale;
0124 u16 system;
0125 u16 volume;
0126 } mpx_audio_modes[] = {
0127 { AUD_MONO, 0x1003, 0x0020, 0x0100, 0x2603,
0128 0x5000, 0x0000, 0x0001, 0x7500 },
0129 { AUD_MONO, 0x1003, 0x0020, 0x0100, 0x2603,
0130 0x5000, 0x0000, 0x0003, 0x7500 },
0131 { AUD_A2, 0x1003, 0x0020, 0x0100, 0x2601,
0132 0x5000, 0x0000, 0x0003, 0x7500 },
0133 { AUD_NICAM, 0x1003, 0x0120, 0x0100, 0x2603,
0134 0x5000, 0x0000, 0x0008, 0x7500 },
0135 { AUD_MONO, 0x1003, 0x0020, 0x0100, 0x2603,
0136 0x7900, 0x0000, 0x000A, 0x7500 },
0137 { AUD_NICAM, 0x1003, 0x0120, 0x0100, 0x2603,
0138 0x7900, 0x0000, 0x000A, 0x7500 },
0139 { AUD_MONO, 0x1003, 0x0020, 0x0100, 0x2603,
0140 0x5000, 0x0000, 0x0004, 0x7500 },
0141 { AUD_A2, 0x1003, 0x0020, 0x0100, 0x2601,
0142 0x5000, 0x0000, 0x0004, 0x7500 },
0143 { AUD_A2, 0x1003, 0x0020, 0x0100, 0x2601,
0144 0x5000, 0x0000, 0x0005, 0x7500 },
0145 { AUD_A2, 0x1003, 0x0020, 0x0100, 0x2601,
0146 0x5000, 0x0000, 0x0007, 0x7500 },
0147 { AUD_NICAM, 0x1003, 0x0120, 0x0100, 0x2603,
0148 0x5000, 0x0000, 0x000B, 0x7500 },
0149 { AUD_MONO, 0x0003, 0x0200, 0x0100, 0x7C03,
0150 0x5000, 0x2200, 0x0009, 0x7500 },
0151 { AUD_NICAM_L, 0x0003, 0x0120, 0x0100, 0x7C03,
0152 0x5000, 0x0000, 0x0009, 0x7500 },
0153 };
0154
0155 #define MPX_NUM_MODES ARRAY_SIZE(mpx_audio_modes)
0156
0157 static int mpx_setup(struct sony_btf_mpx *t)
0158 {
0159 struct i2c_client *client = v4l2_get_subdevdata(&t->sd);
0160 u16 source = 0;
0161 u8 buffer[3];
0162 struct i2c_msg msg;
0163 int mode = t->mpxmode;
0164
0165
0166 buffer[0] = 0x00;
0167 buffer[1] = 0x80;
0168 buffer[2] = 0x00;
0169 msg.addr = client->addr;
0170 msg.flags = 0;
0171 msg.len = 3;
0172 msg.buf = buffer;
0173 i2c_transfer(client->adapter, &msg, 1);
0174 buffer[1] = 0x00;
0175 i2c_transfer(client->adapter, &msg, 1);
0176
0177 if (t->audmode != V4L2_TUNER_MODE_MONO)
0178 mode++;
0179
0180 if (mpx_audio_modes[mode].audio_mode != AUD_MONO) {
0181 switch (t->audmode) {
0182 case V4L2_TUNER_MODE_MONO:
0183 switch (mpx_audio_modes[mode].audio_mode) {
0184 case AUD_A2:
0185 source = mpx_audio_modes[mode].source;
0186 break;
0187 case AUD_NICAM:
0188 source = 0x0000;
0189 break;
0190 case AUD_NICAM_L:
0191 source = 0x0200;
0192 break;
0193 default:
0194 break;
0195 }
0196 break;
0197 case V4L2_TUNER_MODE_STEREO:
0198 source = mpx_audio_modes[mode].source;
0199 break;
0200 case V4L2_TUNER_MODE_LANG1:
0201 source = 0x0300;
0202 break;
0203 case V4L2_TUNER_MODE_LANG2:
0204 source = 0x0400;
0205 break;
0206 }
0207 source |= mpx_audio_modes[mode].source & 0x00ff;
0208 } else
0209 source = mpx_audio_modes[mode].source;
0210
0211 mpx_write(client, 0x10, 0x0030, mpx_audio_modes[mode].modus);
0212 mpx_write(client, 0x12, 0x0008, source);
0213 mpx_write(client, 0x12, 0x0013, mpx_audio_modes[mode].acb);
0214 mpx_write(client, 0x12, 0x000e,
0215 mpx_audio_modes[mode].fm_prescale);
0216 mpx_write(client, 0x12, 0x0010,
0217 mpx_audio_modes[mode].nicam_prescale);
0218 mpx_write(client, 0x12, 0x000d,
0219 mpx_audio_modes[mode].scart_prescale);
0220 mpx_write(client, 0x10, 0x0020, mpx_audio_modes[mode].system);
0221 mpx_write(client, 0x12, 0x0000, mpx_audio_modes[mode].volume);
0222 if (mpx_audio_modes[mode].audio_mode == AUD_A2)
0223 mpx_write(client, 0x10, 0x0022,
0224 t->audmode == V4L2_TUNER_MODE_MONO ? 0x07f0 : 0x0190);
0225
0226 #ifdef MPX_DEBUG
0227 {
0228 u8 buf1[3], buf2[2];
0229 struct i2c_msg msgs[2];
0230
0231 v4l2_info(client,
0232 "MPX registers: %04x %04x %04x %04x %04x %04x %04x %04x\n",
0233 mpx_audio_modes[mode].modus,
0234 source,
0235 mpx_audio_modes[mode].acb,
0236 mpx_audio_modes[mode].fm_prescale,
0237 mpx_audio_modes[mode].nicam_prescale,
0238 mpx_audio_modes[mode].scart_prescale,
0239 mpx_audio_modes[mode].system,
0240 mpx_audio_modes[mode].volume);
0241 buf1[0] = 0x11;
0242 buf1[1] = 0x00;
0243 buf1[2] = 0x7e;
0244 msgs[0].addr = client->addr;
0245 msgs[0].flags = 0;
0246 msgs[0].len = 3;
0247 msgs[0].buf = buf1;
0248 msgs[1].addr = client->addr;
0249 msgs[1].flags = I2C_M_RD;
0250 msgs[1].len = 2;
0251 msgs[1].buf = buf2;
0252 i2c_transfer(client->adapter, msgs, 2);
0253 v4l2_info(client, "MPX system: %02x%02x\n",
0254 buf2[0], buf2[1]);
0255 buf1[0] = 0x11;
0256 buf1[1] = 0x02;
0257 buf1[2] = 0x00;
0258 i2c_transfer(client->adapter, msgs, 2);
0259 v4l2_info(client, "MPX status: %02x%02x\n",
0260 buf2[0], buf2[1]);
0261 }
0262 #endif
0263 return 0;
0264 }
0265
0266
0267 static int sony_btf_mpx_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
0268 {
0269 struct sony_btf_mpx *t = to_state(sd);
0270 int default_mpx_mode = 0;
0271
0272 if (std & V4L2_STD_PAL_BG)
0273 default_mpx_mode = 1;
0274 else if (std & V4L2_STD_PAL_I)
0275 default_mpx_mode = 4;
0276 else if (std & V4L2_STD_PAL_DK)
0277 default_mpx_mode = 6;
0278 else if (std & V4L2_STD_SECAM_L)
0279 default_mpx_mode = 11;
0280
0281 if (default_mpx_mode != t->mpxmode) {
0282 t->mpxmode = default_mpx_mode;
0283 mpx_setup(t);
0284 }
0285 return 0;
0286 }
0287
0288 static int sony_btf_mpx_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
0289 {
0290 struct sony_btf_mpx *t = to_state(sd);
0291
0292 vt->capability = V4L2_TUNER_CAP_NORM |
0293 V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
0294 V4L2_TUNER_CAP_LANG2;
0295 vt->rxsubchans = V4L2_TUNER_SUB_MONO |
0296 V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_LANG1 |
0297 V4L2_TUNER_SUB_LANG2;
0298 vt->audmode = t->audmode;
0299 return 0;
0300 }
0301
0302 static int sony_btf_mpx_s_tuner(struct v4l2_subdev *sd, const struct v4l2_tuner *vt)
0303 {
0304 struct sony_btf_mpx *t = to_state(sd);
0305
0306 if (vt->type != V4L2_TUNER_ANALOG_TV)
0307 return -EINVAL;
0308
0309 if (vt->audmode != t->audmode) {
0310 t->audmode = vt->audmode;
0311 mpx_setup(t);
0312 }
0313 return 0;
0314 }
0315
0316
0317
0318 static const struct v4l2_subdev_tuner_ops sony_btf_mpx_tuner_ops = {
0319 .s_tuner = sony_btf_mpx_s_tuner,
0320 .g_tuner = sony_btf_mpx_g_tuner,
0321 };
0322
0323 static const struct v4l2_subdev_video_ops sony_btf_mpx_video_ops = {
0324 .s_std = sony_btf_mpx_s_std,
0325 };
0326
0327 static const struct v4l2_subdev_ops sony_btf_mpx_ops = {
0328 .tuner = &sony_btf_mpx_tuner_ops,
0329 .video = &sony_btf_mpx_video_ops,
0330 };
0331
0332
0333
0334 static int sony_btf_mpx_probe(struct i2c_client *client,
0335 const struct i2c_device_id *id)
0336 {
0337 struct sony_btf_mpx *t;
0338 struct v4l2_subdev *sd;
0339
0340 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
0341 return -ENODEV;
0342
0343 v4l_info(client, "chip found @ 0x%x (%s)\n",
0344 client->addr << 1, client->adapter->name);
0345
0346 t = devm_kzalloc(&client->dev, sizeof(*t), GFP_KERNEL);
0347 if (t == NULL)
0348 return -ENOMEM;
0349
0350 sd = &t->sd;
0351 v4l2_i2c_subdev_init(sd, client, &sony_btf_mpx_ops);
0352
0353
0354 t->mpxmode = 0;
0355 t->audmode = V4L2_TUNER_MODE_STEREO;
0356
0357 return 0;
0358 }
0359
0360 static int sony_btf_mpx_remove(struct i2c_client *client)
0361 {
0362 struct v4l2_subdev *sd = i2c_get_clientdata(client);
0363
0364 v4l2_device_unregister_subdev(sd);
0365
0366 return 0;
0367 }
0368
0369
0370
0371 static const struct i2c_device_id sony_btf_mpx_id[] = {
0372 { "sony-btf-mpx", 0 },
0373 { }
0374 };
0375 MODULE_DEVICE_TABLE(i2c, sony_btf_mpx_id);
0376
0377 static struct i2c_driver sony_btf_mpx_driver = {
0378 .driver = {
0379 .name = "sony-btf-mpx",
0380 },
0381 .probe = sony_btf_mpx_probe,
0382 .remove = sony_btf_mpx_remove,
0383 .id_table = sony_btf_mpx_id,
0384 };
0385 module_i2c_driver(sony_btf_mpx_driver);