0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/clk.h>
0013 #include <linux/i2c.h>
0014 #include <linux/log2.h>
0015 #include <linux/module.h>
0016 #include <linux/regulator/consumer.h>
0017 #include <linux/slab.h>
0018 #include <linux/videodev2.h>
0019 #include <linux/v4l2-mediabus.h>
0020
0021 #include <media/i2c/mt9t001.h>
0022 #include <media/v4l2-ctrls.h>
0023 #include <media/v4l2-device.h>
0024 #include <media/v4l2-subdev.h>
0025
0026 #define MT9T001_PIXEL_ARRAY_HEIGHT 1568
0027 #define MT9T001_PIXEL_ARRAY_WIDTH 2112
0028
0029 #define MT9T001_CHIP_VERSION 0x00
0030 #define MT9T001_CHIP_ID 0x1621
0031 #define MT9T001_ROW_START 0x01
0032 #define MT9T001_ROW_START_MIN 0
0033 #define MT9T001_ROW_START_DEF 20
0034 #define MT9T001_ROW_START_MAX 1534
0035 #define MT9T001_COLUMN_START 0x02
0036 #define MT9T001_COLUMN_START_MIN 0
0037 #define MT9T001_COLUMN_START_DEF 32
0038 #define MT9T001_COLUMN_START_MAX 2046
0039 #define MT9T001_WINDOW_HEIGHT 0x03
0040 #define MT9T001_WINDOW_HEIGHT_MIN 1
0041 #define MT9T001_WINDOW_HEIGHT_DEF 1535
0042 #define MT9T001_WINDOW_HEIGHT_MAX 1567
0043 #define MT9T001_WINDOW_WIDTH 0x04
0044 #define MT9T001_WINDOW_WIDTH_MIN 1
0045 #define MT9T001_WINDOW_WIDTH_DEF 2047
0046 #define MT9T001_WINDOW_WIDTH_MAX 2111
0047 #define MT9T001_HORIZONTAL_BLANKING 0x05
0048 #define MT9T001_HORIZONTAL_BLANKING_MIN 21
0049 #define MT9T001_HORIZONTAL_BLANKING_MAX 1023
0050 #define MT9T001_VERTICAL_BLANKING 0x06
0051 #define MT9T001_VERTICAL_BLANKING_MIN 3
0052 #define MT9T001_VERTICAL_BLANKING_MAX 1023
0053 #define MT9T001_OUTPUT_CONTROL 0x07
0054 #define MT9T001_OUTPUT_CONTROL_SYNC (1 << 0)
0055 #define MT9T001_OUTPUT_CONTROL_CHIP_ENABLE (1 << 1)
0056 #define MT9T001_OUTPUT_CONTROL_TEST_DATA (1 << 6)
0057 #define MT9T001_OUTPUT_CONTROL_DEF 0x0002
0058 #define MT9T001_SHUTTER_WIDTH_HIGH 0x08
0059 #define MT9T001_SHUTTER_WIDTH_LOW 0x09
0060 #define MT9T001_SHUTTER_WIDTH_MIN 1
0061 #define MT9T001_SHUTTER_WIDTH_DEF 1561
0062 #define MT9T001_SHUTTER_WIDTH_MAX (1024 * 1024)
0063 #define MT9T001_PIXEL_CLOCK 0x0a
0064 #define MT9T001_PIXEL_CLOCK_INVERT (1 << 15)
0065 #define MT9T001_PIXEL_CLOCK_SHIFT_MASK (7 << 8)
0066 #define MT9T001_PIXEL_CLOCK_SHIFT_SHIFT 8
0067 #define MT9T001_PIXEL_CLOCK_DIVIDE_MASK (0x7f << 0)
0068 #define MT9T001_FRAME_RESTART 0x0b
0069 #define MT9T001_SHUTTER_DELAY 0x0c
0070 #define MT9T001_SHUTTER_DELAY_MAX 2047
0071 #define MT9T001_RESET 0x0d
0072 #define MT9T001_READ_MODE1 0x1e
0073 #define MT9T001_READ_MODE_SNAPSHOT (1 << 8)
0074 #define MT9T001_READ_MODE_STROBE_ENABLE (1 << 9)
0075 #define MT9T001_READ_MODE_STROBE_WIDTH (1 << 10)
0076 #define MT9T001_READ_MODE_STROBE_OVERRIDE (1 << 11)
0077 #define MT9T001_READ_MODE2 0x20
0078 #define MT9T001_READ_MODE_BAD_FRAMES (1 << 0)
0079 #define MT9T001_READ_MODE_LINE_VALID_CONTINUOUS (1 << 9)
0080 #define MT9T001_READ_MODE_LINE_VALID_FRAME (1 << 10)
0081 #define MT9T001_READ_MODE3 0x21
0082 #define MT9T001_READ_MODE_GLOBAL_RESET (1 << 0)
0083 #define MT9T001_READ_MODE_GHST_CTL (1 << 1)
0084 #define MT9T001_ROW_ADDRESS_MODE 0x22
0085 #define MT9T001_ROW_SKIP_MASK (7 << 0)
0086 #define MT9T001_ROW_BIN_MASK (3 << 3)
0087 #define MT9T001_ROW_BIN_SHIFT 3
0088 #define MT9T001_COLUMN_ADDRESS_MODE 0x23
0089 #define MT9T001_COLUMN_SKIP_MASK (7 << 0)
0090 #define MT9T001_COLUMN_BIN_MASK (3 << 3)
0091 #define MT9T001_COLUMN_BIN_SHIFT 3
0092 #define MT9T001_GREEN1_GAIN 0x2b
0093 #define MT9T001_BLUE_GAIN 0x2c
0094 #define MT9T001_RED_GAIN 0x2d
0095 #define MT9T001_GREEN2_GAIN 0x2e
0096 #define MT9T001_TEST_DATA 0x32
0097 #define MT9T001_GLOBAL_GAIN 0x35
0098 #define MT9T001_GLOBAL_GAIN_MIN 8
0099 #define MT9T001_GLOBAL_GAIN_MAX 1024
0100 #define MT9T001_BLACK_LEVEL 0x49
0101 #define MT9T001_ROW_BLACK_DEFAULT_OFFSET 0x4b
0102 #define MT9T001_BLC_DELTA_THRESHOLDS 0x5d
0103 #define MT9T001_CAL_THRESHOLDS 0x5f
0104 #define MT9T001_GREEN1_OFFSET 0x60
0105 #define MT9T001_GREEN2_OFFSET 0x61
0106 #define MT9T001_BLACK_LEVEL_CALIBRATION 0x62
0107 #define MT9T001_BLACK_LEVEL_OVERRIDE (1 << 0)
0108 #define MT9T001_BLACK_LEVEL_DISABLE_OFFSET (1 << 1)
0109 #define MT9T001_BLACK_LEVEL_RECALCULATE (1 << 12)
0110 #define MT9T001_BLACK_LEVEL_LOCK_RED_BLUE (1 << 13)
0111 #define MT9T001_BLACK_LEVEL_LOCK_GREEN (1 << 14)
0112 #define MT9T001_RED_OFFSET 0x63
0113 #define MT9T001_BLUE_OFFSET 0x64
0114
0115 struct mt9t001 {
0116 struct v4l2_subdev subdev;
0117 struct media_pad pad;
0118
0119 struct clk *clk;
0120 struct regulator_bulk_data regulators[2];
0121
0122 struct mutex power_lock;
0123 int power_count;
0124
0125 struct v4l2_mbus_framefmt format;
0126 struct v4l2_rect crop;
0127
0128 struct v4l2_ctrl_handler ctrls;
0129 struct v4l2_ctrl *gains[4];
0130
0131 u16 output_control;
0132 u16 black_level;
0133 };
0134
0135 static inline struct mt9t001 *to_mt9t001(struct v4l2_subdev *sd)
0136 {
0137 return container_of(sd, struct mt9t001, subdev);
0138 }
0139
0140 static int mt9t001_read(struct i2c_client *client, u8 reg)
0141 {
0142 return i2c_smbus_read_word_swapped(client, reg);
0143 }
0144
0145 static int mt9t001_write(struct i2c_client *client, u8 reg, u16 data)
0146 {
0147 return i2c_smbus_write_word_swapped(client, reg, data);
0148 }
0149
0150 static int mt9t001_set_output_control(struct mt9t001 *mt9t001, u16 clear,
0151 u16 set)
0152 {
0153 struct i2c_client *client = v4l2_get_subdevdata(&mt9t001->subdev);
0154 u16 value = (mt9t001->output_control & ~clear) | set;
0155 int ret;
0156
0157 if (value == mt9t001->output_control)
0158 return 0;
0159
0160 ret = mt9t001_write(client, MT9T001_OUTPUT_CONTROL, value);
0161 if (ret < 0)
0162 return ret;
0163
0164 mt9t001->output_control = value;
0165 return 0;
0166 }
0167
0168 static int mt9t001_reset(struct mt9t001 *mt9t001)
0169 {
0170 struct i2c_client *client = v4l2_get_subdevdata(&mt9t001->subdev);
0171 int ret;
0172
0173
0174 ret = mt9t001_write(client, MT9T001_RESET, 1);
0175 if (ret < 0)
0176 return ret;
0177
0178 ret = mt9t001_write(client, MT9T001_RESET, 0);
0179 if (ret < 0)
0180 return ret;
0181
0182 mt9t001->output_control = MT9T001_OUTPUT_CONTROL_DEF;
0183
0184 return mt9t001_set_output_control(mt9t001,
0185 MT9T001_OUTPUT_CONTROL_CHIP_ENABLE,
0186 0);
0187 }
0188
0189 static int mt9t001_power_on(struct mt9t001 *mt9t001)
0190 {
0191 int ret;
0192
0193
0194 ret = regulator_bulk_enable(ARRAY_SIZE(mt9t001->regulators),
0195 mt9t001->regulators);
0196 if (ret < 0)
0197 return ret;
0198
0199
0200 ret = clk_prepare_enable(mt9t001->clk);
0201 if (ret < 0)
0202 regulator_bulk_disable(ARRAY_SIZE(mt9t001->regulators),
0203 mt9t001->regulators);
0204
0205 return ret;
0206 }
0207
0208 static void mt9t001_power_off(struct mt9t001 *mt9t001)
0209 {
0210 regulator_bulk_disable(ARRAY_SIZE(mt9t001->regulators),
0211 mt9t001->regulators);
0212
0213 clk_disable_unprepare(mt9t001->clk);
0214 }
0215
0216 static int __mt9t001_set_power(struct mt9t001 *mt9t001, bool on)
0217 {
0218 struct i2c_client *client = v4l2_get_subdevdata(&mt9t001->subdev);
0219 int ret;
0220
0221 if (!on) {
0222 mt9t001_power_off(mt9t001);
0223 return 0;
0224 }
0225
0226 ret = mt9t001_power_on(mt9t001);
0227 if (ret < 0)
0228 return ret;
0229
0230 ret = mt9t001_reset(mt9t001);
0231 if (ret < 0) {
0232 dev_err(&client->dev, "Failed to reset the camera\n");
0233 goto e_power;
0234 }
0235
0236 ret = v4l2_ctrl_handler_setup(&mt9t001->ctrls);
0237 if (ret < 0) {
0238 dev_err(&client->dev, "Failed to set up control handlers\n");
0239 goto e_power;
0240 }
0241
0242 return 0;
0243
0244 e_power:
0245 mt9t001_power_off(mt9t001);
0246
0247 return ret;
0248 }
0249
0250
0251
0252
0253
0254 static struct v4l2_mbus_framefmt *
0255 __mt9t001_get_pad_format(struct mt9t001 *mt9t001,
0256 struct v4l2_subdev_state *sd_state,
0257 unsigned int pad, enum v4l2_subdev_format_whence which)
0258 {
0259 switch (which) {
0260 case V4L2_SUBDEV_FORMAT_TRY:
0261 return v4l2_subdev_get_try_format(&mt9t001->subdev, sd_state,
0262 pad);
0263 case V4L2_SUBDEV_FORMAT_ACTIVE:
0264 return &mt9t001->format;
0265 default:
0266 return NULL;
0267 }
0268 }
0269
0270 static struct v4l2_rect *
0271 __mt9t001_get_pad_crop(struct mt9t001 *mt9t001,
0272 struct v4l2_subdev_state *sd_state,
0273 unsigned int pad, enum v4l2_subdev_format_whence which)
0274 {
0275 switch (which) {
0276 case V4L2_SUBDEV_FORMAT_TRY:
0277 return v4l2_subdev_get_try_crop(&mt9t001->subdev, sd_state,
0278 pad);
0279 case V4L2_SUBDEV_FORMAT_ACTIVE:
0280 return &mt9t001->crop;
0281 default:
0282 return NULL;
0283 }
0284 }
0285
0286 static int mt9t001_s_stream(struct v4l2_subdev *subdev, int enable)
0287 {
0288 const u16 mode = MT9T001_OUTPUT_CONTROL_CHIP_ENABLE;
0289 struct i2c_client *client = v4l2_get_subdevdata(subdev);
0290 struct mt9t001_platform_data *pdata = client->dev.platform_data;
0291 struct mt9t001 *mt9t001 = to_mt9t001(subdev);
0292 struct v4l2_mbus_framefmt *format = &mt9t001->format;
0293 struct v4l2_rect *crop = &mt9t001->crop;
0294 unsigned int hratio;
0295 unsigned int vratio;
0296 int ret;
0297
0298 if (!enable)
0299 return mt9t001_set_output_control(mt9t001, mode, 0);
0300
0301
0302 if (pdata->clk_pol) {
0303 ret = mt9t001_write(client, MT9T001_PIXEL_CLOCK,
0304 MT9T001_PIXEL_CLOCK_INVERT);
0305 if (ret < 0)
0306 return ret;
0307 }
0308
0309
0310 hratio = DIV_ROUND_CLOSEST(crop->width, format->width);
0311 vratio = DIV_ROUND_CLOSEST(crop->height, format->height);
0312
0313 ret = mt9t001_write(client, MT9T001_ROW_ADDRESS_MODE, hratio - 1);
0314 if (ret < 0)
0315 return ret;
0316
0317 ret = mt9t001_write(client, MT9T001_COLUMN_ADDRESS_MODE, vratio - 1);
0318 if (ret < 0)
0319 return ret;
0320
0321 ret = mt9t001_write(client, MT9T001_COLUMN_START, crop->left);
0322 if (ret < 0)
0323 return ret;
0324
0325 ret = mt9t001_write(client, MT9T001_ROW_START, crop->top);
0326 if (ret < 0)
0327 return ret;
0328
0329 ret = mt9t001_write(client, MT9T001_WINDOW_WIDTH, crop->width - 1);
0330 if (ret < 0)
0331 return ret;
0332
0333 ret = mt9t001_write(client, MT9T001_WINDOW_HEIGHT, crop->height - 1);
0334 if (ret < 0)
0335 return ret;
0336
0337
0338 return mt9t001_set_output_control(mt9t001, 0, mode);
0339 }
0340
0341 static int mt9t001_enum_mbus_code(struct v4l2_subdev *subdev,
0342 struct v4l2_subdev_state *sd_state,
0343 struct v4l2_subdev_mbus_code_enum *code)
0344 {
0345 if (code->index > 0)
0346 return -EINVAL;
0347
0348 code->code = MEDIA_BUS_FMT_SGRBG10_1X10;
0349 return 0;
0350 }
0351
0352 static int mt9t001_enum_frame_size(struct v4l2_subdev *subdev,
0353 struct v4l2_subdev_state *sd_state,
0354 struct v4l2_subdev_frame_size_enum *fse)
0355 {
0356 if (fse->index >= 8 || fse->code != MEDIA_BUS_FMT_SGRBG10_1X10)
0357 return -EINVAL;
0358
0359 fse->min_width = (MT9T001_WINDOW_WIDTH_DEF + 1) / fse->index;
0360 fse->max_width = fse->min_width;
0361 fse->min_height = (MT9T001_WINDOW_HEIGHT_DEF + 1) / fse->index;
0362 fse->max_height = fse->min_height;
0363
0364 return 0;
0365 }
0366
0367 static int mt9t001_get_format(struct v4l2_subdev *subdev,
0368 struct v4l2_subdev_state *sd_state,
0369 struct v4l2_subdev_format *format)
0370 {
0371 struct mt9t001 *mt9t001 = to_mt9t001(subdev);
0372
0373 format->format = *__mt9t001_get_pad_format(mt9t001, sd_state,
0374 format->pad,
0375 format->which);
0376 return 0;
0377 }
0378
0379 static int mt9t001_set_format(struct v4l2_subdev *subdev,
0380 struct v4l2_subdev_state *sd_state,
0381 struct v4l2_subdev_format *format)
0382 {
0383 struct mt9t001 *mt9t001 = to_mt9t001(subdev);
0384 struct v4l2_mbus_framefmt *__format;
0385 struct v4l2_rect *__crop;
0386 unsigned int width;
0387 unsigned int height;
0388 unsigned int hratio;
0389 unsigned int vratio;
0390
0391 __crop = __mt9t001_get_pad_crop(mt9t001, sd_state, format->pad,
0392 format->which);
0393
0394
0395 width = clamp_t(unsigned int, ALIGN(format->format.width, 2),
0396 max_t(unsigned int, __crop->width / 8,
0397 MT9T001_WINDOW_HEIGHT_MIN + 1),
0398 __crop->width);
0399 height = clamp_t(unsigned int, ALIGN(format->format.height, 2),
0400 max_t(unsigned int, __crop->height / 8,
0401 MT9T001_WINDOW_HEIGHT_MIN + 1),
0402 __crop->height);
0403
0404 hratio = DIV_ROUND_CLOSEST(__crop->width, width);
0405 vratio = DIV_ROUND_CLOSEST(__crop->height, height);
0406
0407 __format = __mt9t001_get_pad_format(mt9t001, sd_state, format->pad,
0408 format->which);
0409 __format->width = __crop->width / hratio;
0410 __format->height = __crop->height / vratio;
0411
0412 format->format = *__format;
0413
0414 return 0;
0415 }
0416
0417 static int mt9t001_get_selection(struct v4l2_subdev *subdev,
0418 struct v4l2_subdev_state *sd_state,
0419 struct v4l2_subdev_selection *sel)
0420 {
0421 struct mt9t001 *mt9t001 = to_mt9t001(subdev);
0422
0423 if (sel->target != V4L2_SEL_TGT_CROP)
0424 return -EINVAL;
0425
0426 sel->r = *__mt9t001_get_pad_crop(mt9t001, sd_state, sel->pad,
0427 sel->which);
0428 return 0;
0429 }
0430
0431 static int mt9t001_set_selection(struct v4l2_subdev *subdev,
0432 struct v4l2_subdev_state *sd_state,
0433 struct v4l2_subdev_selection *sel)
0434 {
0435 struct mt9t001 *mt9t001 = to_mt9t001(subdev);
0436 struct v4l2_mbus_framefmt *__format;
0437 struct v4l2_rect *__crop;
0438 struct v4l2_rect rect;
0439
0440 if (sel->target != V4L2_SEL_TGT_CROP)
0441 return -EINVAL;
0442
0443
0444
0445
0446 rect.left = clamp(ALIGN(sel->r.left, 2),
0447 MT9T001_COLUMN_START_MIN,
0448 MT9T001_COLUMN_START_MAX);
0449 rect.top = clamp(ALIGN(sel->r.top, 2),
0450 MT9T001_ROW_START_MIN,
0451 MT9T001_ROW_START_MAX);
0452 rect.width = clamp_t(unsigned int, ALIGN(sel->r.width, 2),
0453 MT9T001_WINDOW_WIDTH_MIN + 1,
0454 MT9T001_WINDOW_WIDTH_MAX + 1);
0455 rect.height = clamp_t(unsigned int, ALIGN(sel->r.height, 2),
0456 MT9T001_WINDOW_HEIGHT_MIN + 1,
0457 MT9T001_WINDOW_HEIGHT_MAX + 1);
0458
0459 rect.width = min_t(unsigned int, rect.width,
0460 MT9T001_PIXEL_ARRAY_WIDTH - rect.left);
0461 rect.height = min_t(unsigned int, rect.height,
0462 MT9T001_PIXEL_ARRAY_HEIGHT - rect.top);
0463
0464 __crop = __mt9t001_get_pad_crop(mt9t001, sd_state, sel->pad,
0465 sel->which);
0466
0467 if (rect.width != __crop->width || rect.height != __crop->height) {
0468
0469
0470
0471 __format = __mt9t001_get_pad_format(mt9t001, sd_state,
0472 sel->pad,
0473 sel->which);
0474 __format->width = rect.width;
0475 __format->height = rect.height;
0476 }
0477
0478 *__crop = rect;
0479 sel->r = rect;
0480
0481 return 0;
0482 }
0483
0484
0485
0486
0487
0488 #define V4L2_CID_TEST_PATTERN_COLOR (V4L2_CID_USER_BASE | 0x1001)
0489 #define V4L2_CID_BLACK_LEVEL_AUTO (V4L2_CID_USER_BASE | 0x1002)
0490 #define V4L2_CID_BLACK_LEVEL_OFFSET (V4L2_CID_USER_BASE | 0x1003)
0491 #define V4L2_CID_BLACK_LEVEL_CALIBRATE (V4L2_CID_USER_BASE | 0x1004)
0492
0493 #define V4L2_CID_GAIN_RED (V4L2_CTRL_CLASS_CAMERA | 0x1001)
0494 #define V4L2_CID_GAIN_GREEN_RED (V4L2_CTRL_CLASS_CAMERA | 0x1002)
0495 #define V4L2_CID_GAIN_GREEN_BLUE (V4L2_CTRL_CLASS_CAMERA | 0x1003)
0496 #define V4L2_CID_GAIN_BLUE (V4L2_CTRL_CLASS_CAMERA | 0x1004)
0497
0498 static u16 mt9t001_gain_value(s32 *gain)
0499 {
0500
0501
0502
0503
0504
0505
0506
0507
0508
0509
0510
0511
0512
0513
0514 if (*gain <= 32)
0515 return *gain;
0516
0517 if (*gain <= 64) {
0518 *gain &= ~1;
0519 return (1 << 6) | (*gain >> 1);
0520 }
0521
0522 *gain &= ~7;
0523 return ((*gain - 64) << 5) | (1 << 6) | 32;
0524 }
0525
0526 static int mt9t001_ctrl_freeze(struct mt9t001 *mt9t001, bool freeze)
0527 {
0528 return mt9t001_set_output_control(mt9t001,
0529 freeze ? 0 : MT9T001_OUTPUT_CONTROL_SYNC,
0530 freeze ? MT9T001_OUTPUT_CONTROL_SYNC : 0);
0531 }
0532
0533 static int mt9t001_s_ctrl(struct v4l2_ctrl *ctrl)
0534 {
0535 static const u8 gains[4] = {
0536 MT9T001_RED_GAIN, MT9T001_GREEN1_GAIN,
0537 MT9T001_GREEN2_GAIN, MT9T001_BLUE_GAIN
0538 };
0539
0540 struct mt9t001 *mt9t001 =
0541 container_of(ctrl->handler, struct mt9t001, ctrls);
0542 struct i2c_client *client = v4l2_get_subdevdata(&mt9t001->subdev);
0543 unsigned int count;
0544 unsigned int i;
0545 u16 value;
0546 int ret;
0547
0548 switch (ctrl->id) {
0549 case V4L2_CID_GAIN_RED:
0550 case V4L2_CID_GAIN_GREEN_RED:
0551 case V4L2_CID_GAIN_GREEN_BLUE:
0552 case V4L2_CID_GAIN_BLUE:
0553
0554
0555
0556
0557 for (i = 0, count = 0; i < 4; ++i) {
0558 struct v4l2_ctrl *gain = mt9t001->gains[i];
0559
0560 if (gain->val != gain->cur.val)
0561 count++;
0562 }
0563
0564 if (count > 1) {
0565 ret = mt9t001_ctrl_freeze(mt9t001, true);
0566 if (ret < 0)
0567 return ret;
0568 }
0569
0570
0571 for (i = 0; i < 4; ++i) {
0572 struct v4l2_ctrl *gain = mt9t001->gains[i];
0573
0574 if (gain->val == gain->cur.val)
0575 continue;
0576
0577 value = mt9t001_gain_value(&gain->val);
0578 ret = mt9t001_write(client, gains[i], value);
0579 if (ret < 0) {
0580 mt9t001_ctrl_freeze(mt9t001, false);
0581 return ret;
0582 }
0583 }
0584
0585
0586 if (count > 1) {
0587 ret = mt9t001_ctrl_freeze(mt9t001, false);
0588 if (ret < 0)
0589 return ret;
0590 }
0591
0592 break;
0593
0594 case V4L2_CID_EXPOSURE:
0595 ret = mt9t001_write(client, MT9T001_SHUTTER_WIDTH_LOW,
0596 ctrl->val & 0xffff);
0597 if (ret < 0)
0598 return ret;
0599
0600 return mt9t001_write(client, MT9T001_SHUTTER_WIDTH_HIGH,
0601 ctrl->val >> 16);
0602
0603 case V4L2_CID_TEST_PATTERN:
0604 return mt9t001_set_output_control(mt9t001,
0605 ctrl->val ? 0 : MT9T001_OUTPUT_CONTROL_TEST_DATA,
0606 ctrl->val ? MT9T001_OUTPUT_CONTROL_TEST_DATA : 0);
0607
0608 case V4L2_CID_TEST_PATTERN_COLOR:
0609 return mt9t001_write(client, MT9T001_TEST_DATA, ctrl->val << 2);
0610
0611 case V4L2_CID_BLACK_LEVEL_AUTO:
0612 value = ctrl->val ? 0 : MT9T001_BLACK_LEVEL_OVERRIDE;
0613 ret = mt9t001_write(client, MT9T001_BLACK_LEVEL_CALIBRATION,
0614 value);
0615 if (ret < 0)
0616 return ret;
0617
0618 mt9t001->black_level = value;
0619 break;
0620
0621 case V4L2_CID_BLACK_LEVEL_OFFSET:
0622 ret = mt9t001_write(client, MT9T001_GREEN1_OFFSET, ctrl->val);
0623 if (ret < 0)
0624 return ret;
0625
0626 ret = mt9t001_write(client, MT9T001_GREEN2_OFFSET, ctrl->val);
0627 if (ret < 0)
0628 return ret;
0629
0630 ret = mt9t001_write(client, MT9T001_RED_OFFSET, ctrl->val);
0631 if (ret < 0)
0632 return ret;
0633
0634 return mt9t001_write(client, MT9T001_BLUE_OFFSET, ctrl->val);
0635
0636 case V4L2_CID_BLACK_LEVEL_CALIBRATE:
0637 return mt9t001_write(client, MT9T001_BLACK_LEVEL_CALIBRATION,
0638 MT9T001_BLACK_LEVEL_RECALCULATE |
0639 mt9t001->black_level);
0640 }
0641
0642 return 0;
0643 }
0644
0645 static const struct v4l2_ctrl_ops mt9t001_ctrl_ops = {
0646 .s_ctrl = mt9t001_s_ctrl,
0647 };
0648
0649 static const char * const mt9t001_test_pattern_menu[] = {
0650 "Disabled",
0651 "Enabled",
0652 };
0653
0654 static const struct v4l2_ctrl_config mt9t001_ctrls[] = {
0655 {
0656 .ops = &mt9t001_ctrl_ops,
0657 .id = V4L2_CID_TEST_PATTERN_COLOR,
0658 .type = V4L2_CTRL_TYPE_INTEGER,
0659 .name = "Test Pattern Color",
0660 .min = 0,
0661 .max = 1023,
0662 .step = 1,
0663 .def = 0,
0664 .flags = 0,
0665 }, {
0666 .ops = &mt9t001_ctrl_ops,
0667 .id = V4L2_CID_BLACK_LEVEL_AUTO,
0668 .type = V4L2_CTRL_TYPE_BOOLEAN,
0669 .name = "Black Level, Auto",
0670 .min = 0,
0671 .max = 1,
0672 .step = 1,
0673 .def = 1,
0674 .flags = 0,
0675 }, {
0676 .ops = &mt9t001_ctrl_ops,
0677 .id = V4L2_CID_BLACK_LEVEL_OFFSET,
0678 .type = V4L2_CTRL_TYPE_INTEGER,
0679 .name = "Black Level, Offset",
0680 .min = -256,
0681 .max = 255,
0682 .step = 1,
0683 .def = 32,
0684 .flags = 0,
0685 }, {
0686 .ops = &mt9t001_ctrl_ops,
0687 .id = V4L2_CID_BLACK_LEVEL_CALIBRATE,
0688 .type = V4L2_CTRL_TYPE_BUTTON,
0689 .name = "Black Level, Calibrate",
0690 .min = 0,
0691 .max = 0,
0692 .step = 0,
0693 .def = 0,
0694 .flags = V4L2_CTRL_FLAG_WRITE_ONLY,
0695 },
0696 };
0697
0698 static const struct v4l2_ctrl_config mt9t001_gains[] = {
0699 {
0700 .ops = &mt9t001_ctrl_ops,
0701 .id = V4L2_CID_GAIN_RED,
0702 .type = V4L2_CTRL_TYPE_INTEGER,
0703 .name = "Gain, Red",
0704 .min = MT9T001_GLOBAL_GAIN_MIN,
0705 .max = MT9T001_GLOBAL_GAIN_MAX,
0706 .step = 1,
0707 .def = MT9T001_GLOBAL_GAIN_MIN,
0708 .flags = 0,
0709 }, {
0710 .ops = &mt9t001_ctrl_ops,
0711 .id = V4L2_CID_GAIN_GREEN_RED,
0712 .type = V4L2_CTRL_TYPE_INTEGER,
0713 .name = "Gain, Green (R)",
0714 .min = MT9T001_GLOBAL_GAIN_MIN,
0715 .max = MT9T001_GLOBAL_GAIN_MAX,
0716 .step = 1,
0717 .def = MT9T001_GLOBAL_GAIN_MIN,
0718 .flags = 0,
0719 }, {
0720 .ops = &mt9t001_ctrl_ops,
0721 .id = V4L2_CID_GAIN_GREEN_BLUE,
0722 .type = V4L2_CTRL_TYPE_INTEGER,
0723 .name = "Gain, Green (B)",
0724 .min = MT9T001_GLOBAL_GAIN_MIN,
0725 .max = MT9T001_GLOBAL_GAIN_MAX,
0726 .step = 1,
0727 .def = MT9T001_GLOBAL_GAIN_MIN,
0728 .flags = 0,
0729 }, {
0730 .ops = &mt9t001_ctrl_ops,
0731 .id = V4L2_CID_GAIN_BLUE,
0732 .type = V4L2_CTRL_TYPE_INTEGER,
0733 .name = "Gain, Blue",
0734 .min = MT9T001_GLOBAL_GAIN_MIN,
0735 .max = MT9T001_GLOBAL_GAIN_MAX,
0736 .step = 1,
0737 .def = MT9T001_GLOBAL_GAIN_MIN,
0738 .flags = 0,
0739 },
0740 };
0741
0742
0743
0744
0745
0746 static int mt9t001_set_power(struct v4l2_subdev *subdev, int on)
0747 {
0748 struct mt9t001 *mt9t001 = to_mt9t001(subdev);
0749 int ret = 0;
0750
0751 mutex_lock(&mt9t001->power_lock);
0752
0753
0754
0755
0756 if (mt9t001->power_count == !on) {
0757 ret = __mt9t001_set_power(mt9t001, !!on);
0758 if (ret < 0)
0759 goto out;
0760 }
0761
0762
0763 mt9t001->power_count += on ? 1 : -1;
0764 WARN_ON(mt9t001->power_count < 0);
0765
0766 out:
0767 mutex_unlock(&mt9t001->power_lock);
0768 return ret;
0769 }
0770
0771
0772
0773
0774
0775 static int mt9t001_registered(struct v4l2_subdev *subdev)
0776 {
0777 struct i2c_client *client = v4l2_get_subdevdata(subdev);
0778 struct mt9t001 *mt9t001 = to_mt9t001(subdev);
0779 s32 data;
0780 int ret;
0781
0782 ret = mt9t001_power_on(mt9t001);
0783 if (ret < 0) {
0784 dev_err(&client->dev, "MT9T001 power up failed\n");
0785 return ret;
0786 }
0787
0788
0789 data = mt9t001_read(client, MT9T001_CHIP_VERSION);
0790 mt9t001_power_off(mt9t001);
0791
0792 if (data != MT9T001_CHIP_ID) {
0793 dev_err(&client->dev,
0794 "MT9T001 not detected, wrong version 0x%04x\n", data);
0795 return -ENODEV;
0796 }
0797
0798 dev_info(&client->dev, "MT9T001 detected at address 0x%02x\n",
0799 client->addr);
0800
0801 return 0;
0802 }
0803
0804 static int mt9t001_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
0805 {
0806 struct v4l2_mbus_framefmt *format;
0807 struct v4l2_rect *crop;
0808
0809 crop = v4l2_subdev_get_try_crop(subdev, fh->state, 0);
0810 crop->left = MT9T001_COLUMN_START_DEF;
0811 crop->top = MT9T001_ROW_START_DEF;
0812 crop->width = MT9T001_WINDOW_WIDTH_DEF + 1;
0813 crop->height = MT9T001_WINDOW_HEIGHT_DEF + 1;
0814
0815 format = v4l2_subdev_get_try_format(subdev, fh->state, 0);
0816 format->code = MEDIA_BUS_FMT_SGRBG10_1X10;
0817 format->width = MT9T001_WINDOW_WIDTH_DEF + 1;
0818 format->height = MT9T001_WINDOW_HEIGHT_DEF + 1;
0819 format->field = V4L2_FIELD_NONE;
0820 format->colorspace = V4L2_COLORSPACE_SRGB;
0821
0822 return mt9t001_set_power(subdev, 1);
0823 }
0824
0825 static int mt9t001_close(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
0826 {
0827 return mt9t001_set_power(subdev, 0);
0828 }
0829
0830 static const struct v4l2_subdev_core_ops mt9t001_subdev_core_ops = {
0831 .s_power = mt9t001_set_power,
0832 };
0833
0834 static const struct v4l2_subdev_video_ops mt9t001_subdev_video_ops = {
0835 .s_stream = mt9t001_s_stream,
0836 };
0837
0838 static const struct v4l2_subdev_pad_ops mt9t001_subdev_pad_ops = {
0839 .enum_mbus_code = mt9t001_enum_mbus_code,
0840 .enum_frame_size = mt9t001_enum_frame_size,
0841 .get_fmt = mt9t001_get_format,
0842 .set_fmt = mt9t001_set_format,
0843 .get_selection = mt9t001_get_selection,
0844 .set_selection = mt9t001_set_selection,
0845 };
0846
0847 static const struct v4l2_subdev_ops mt9t001_subdev_ops = {
0848 .core = &mt9t001_subdev_core_ops,
0849 .video = &mt9t001_subdev_video_ops,
0850 .pad = &mt9t001_subdev_pad_ops,
0851 };
0852
0853 static const struct v4l2_subdev_internal_ops mt9t001_subdev_internal_ops = {
0854 .registered = mt9t001_registered,
0855 .open = mt9t001_open,
0856 .close = mt9t001_close,
0857 };
0858
0859 static int mt9t001_probe(struct i2c_client *client,
0860 const struct i2c_device_id *did)
0861 {
0862 struct mt9t001_platform_data *pdata = client->dev.platform_data;
0863 struct mt9t001 *mt9t001;
0864 unsigned int i;
0865 int ret;
0866
0867 if (pdata == NULL) {
0868 dev_err(&client->dev, "No platform data\n");
0869 return -EINVAL;
0870 }
0871
0872 if (!i2c_check_functionality(client->adapter,
0873 I2C_FUNC_SMBUS_WORD_DATA)) {
0874 dev_warn(&client->adapter->dev,
0875 "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
0876 return -EIO;
0877 }
0878
0879 mt9t001 = devm_kzalloc(&client->dev, sizeof(*mt9t001), GFP_KERNEL);
0880 if (!mt9t001)
0881 return -ENOMEM;
0882
0883 mutex_init(&mt9t001->power_lock);
0884 mt9t001->output_control = MT9T001_OUTPUT_CONTROL_DEF;
0885
0886 mt9t001->regulators[0].supply = "vdd";
0887 mt9t001->regulators[1].supply = "vaa";
0888
0889 ret = devm_regulator_bulk_get(&client->dev, 2, mt9t001->regulators);
0890 if (ret < 0) {
0891 dev_err(&client->dev, "Unable to get regulators\n");
0892 return ret;
0893 }
0894
0895 mt9t001->clk = devm_clk_get(&client->dev, NULL);
0896 if (IS_ERR(mt9t001->clk)) {
0897 dev_err(&client->dev, "Unable to get clock\n");
0898 return PTR_ERR(mt9t001->clk);
0899 }
0900
0901 v4l2_ctrl_handler_init(&mt9t001->ctrls, ARRAY_SIZE(mt9t001_ctrls) +
0902 ARRAY_SIZE(mt9t001_gains) + 4);
0903
0904 v4l2_ctrl_new_std(&mt9t001->ctrls, &mt9t001_ctrl_ops,
0905 V4L2_CID_EXPOSURE, MT9T001_SHUTTER_WIDTH_MIN,
0906 MT9T001_SHUTTER_WIDTH_MAX, 1,
0907 MT9T001_SHUTTER_WIDTH_DEF);
0908 v4l2_ctrl_new_std(&mt9t001->ctrls, &mt9t001_ctrl_ops,
0909 V4L2_CID_BLACK_LEVEL, 1, 1, 1, 1);
0910 v4l2_ctrl_new_std(&mt9t001->ctrls, &mt9t001_ctrl_ops,
0911 V4L2_CID_PIXEL_RATE, pdata->ext_clk, pdata->ext_clk,
0912 1, pdata->ext_clk);
0913 v4l2_ctrl_new_std_menu_items(&mt9t001->ctrls, &mt9t001_ctrl_ops,
0914 V4L2_CID_TEST_PATTERN,
0915 ARRAY_SIZE(mt9t001_test_pattern_menu) - 1, 0,
0916 0, mt9t001_test_pattern_menu);
0917
0918 for (i = 0; i < ARRAY_SIZE(mt9t001_ctrls); ++i)
0919 v4l2_ctrl_new_custom(&mt9t001->ctrls, &mt9t001_ctrls[i], NULL);
0920
0921 for (i = 0; i < ARRAY_SIZE(mt9t001_gains); ++i)
0922 mt9t001->gains[i] = v4l2_ctrl_new_custom(&mt9t001->ctrls,
0923 &mt9t001_gains[i], NULL);
0924
0925 v4l2_ctrl_cluster(ARRAY_SIZE(mt9t001_gains), mt9t001->gains);
0926
0927 mt9t001->subdev.ctrl_handler = &mt9t001->ctrls;
0928
0929 if (mt9t001->ctrls.error) {
0930 printk(KERN_INFO "%s: control initialization error %d\n",
0931 __func__, mt9t001->ctrls.error);
0932 ret = -EINVAL;
0933 goto done;
0934 }
0935
0936 mt9t001->crop.left = MT9T001_COLUMN_START_DEF;
0937 mt9t001->crop.top = MT9T001_ROW_START_DEF;
0938 mt9t001->crop.width = MT9T001_WINDOW_WIDTH_DEF + 1;
0939 mt9t001->crop.height = MT9T001_WINDOW_HEIGHT_DEF + 1;
0940
0941 mt9t001->format.code = MEDIA_BUS_FMT_SGRBG10_1X10;
0942 mt9t001->format.width = MT9T001_WINDOW_WIDTH_DEF + 1;
0943 mt9t001->format.height = MT9T001_WINDOW_HEIGHT_DEF + 1;
0944 mt9t001->format.field = V4L2_FIELD_NONE;
0945 mt9t001->format.colorspace = V4L2_COLORSPACE_SRGB;
0946
0947 v4l2_i2c_subdev_init(&mt9t001->subdev, client, &mt9t001_subdev_ops);
0948 mt9t001->subdev.internal_ops = &mt9t001_subdev_internal_ops;
0949 mt9t001->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
0950
0951 mt9t001->subdev.entity.function = MEDIA_ENT_F_CAM_SENSOR;
0952 mt9t001->pad.flags = MEDIA_PAD_FL_SOURCE;
0953 ret = media_entity_pads_init(&mt9t001->subdev.entity, 1, &mt9t001->pad);
0954
0955 done:
0956 if (ret < 0) {
0957 v4l2_ctrl_handler_free(&mt9t001->ctrls);
0958 media_entity_cleanup(&mt9t001->subdev.entity);
0959 }
0960
0961 return ret;
0962 }
0963
0964 static int mt9t001_remove(struct i2c_client *client)
0965 {
0966 struct v4l2_subdev *subdev = i2c_get_clientdata(client);
0967 struct mt9t001 *mt9t001 = to_mt9t001(subdev);
0968
0969 v4l2_ctrl_handler_free(&mt9t001->ctrls);
0970 v4l2_device_unregister_subdev(subdev);
0971 media_entity_cleanup(&subdev->entity);
0972 return 0;
0973 }
0974
0975 static const struct i2c_device_id mt9t001_id[] = {
0976 { "mt9t001", 0 },
0977 { }
0978 };
0979 MODULE_DEVICE_TABLE(i2c, mt9t001_id);
0980
0981 static struct i2c_driver mt9t001_driver = {
0982 .driver = {
0983 .name = "mt9t001",
0984 },
0985 .probe = mt9t001_probe,
0986 .remove = mt9t001_remove,
0987 .id_table = mt9t001_id,
0988 };
0989
0990 module_i2c_driver(mt9t001_driver);
0991
0992 MODULE_DESCRIPTION("Aptina (Micron) MT9T001 Camera driver");
0993 MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
0994 MODULE_LICENSE("GPL");