0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/delay.h>
0010 #include <linux/i2c.h>
0011 #include <linux/module.h>
0012 #include <linux/of_graph.h>
0013 #include <linux/regmap.h>
0014
0015 #include <media/v4l2-ctrls.h>
0016 #include <media/v4l2-fwnode.h>
0017 #include <media/v4l2-subdev.h>
0018
0019 #define MAX96712_ID 0x20
0020
0021 #define MAX96712_DPLL_FREQ 1000
0022
0023 enum max96712_pattern {
0024 MAX96712_PATTERN_CHECKERBOARD = 0,
0025 MAX96712_PATTERN_GRADIENT,
0026 };
0027
0028 struct max96712_priv {
0029 struct i2c_client *client;
0030 struct regmap *regmap;
0031 struct gpio_desc *gpiod_pwdn;
0032
0033 struct v4l2_mbus_config_mipi_csi2 mipi;
0034
0035 struct v4l2_subdev sd;
0036 struct v4l2_ctrl_handler ctrl_handler;
0037 struct media_pad pads[1];
0038
0039 enum max96712_pattern pattern;
0040 };
0041
0042 static int max96712_read(struct max96712_priv *priv, int reg)
0043 {
0044 int ret, val;
0045
0046 ret = regmap_read(priv->regmap, reg, &val);
0047 if (ret) {
0048 dev_err(&priv->client->dev, "read 0x%04x failed\n", reg);
0049 return ret;
0050 }
0051
0052 return val;
0053 }
0054
0055 static int max96712_write(struct max96712_priv *priv, unsigned int reg, u8 val)
0056 {
0057 int ret;
0058
0059 ret = regmap_write(priv->regmap, reg, val);
0060 if (ret)
0061 dev_err(&priv->client->dev, "write 0x%04x failed\n", reg);
0062
0063 return ret;
0064 }
0065
0066 static int max96712_update_bits(struct max96712_priv *priv, unsigned int reg,
0067 u8 mask, u8 val)
0068 {
0069 int ret;
0070
0071 ret = regmap_update_bits(priv->regmap, reg, mask, val);
0072 if (ret)
0073 dev_err(&priv->client->dev, "update 0x%04x failed\n", reg);
0074
0075 return ret;
0076 }
0077
0078 static int max96712_write_bulk(struct max96712_priv *priv, unsigned int reg,
0079 const void *val, size_t val_count)
0080 {
0081 int ret;
0082
0083 ret = regmap_bulk_write(priv->regmap, reg, val, val_count);
0084 if (ret)
0085 dev_err(&priv->client->dev, "bulk write 0x%04x failed\n", reg);
0086
0087 return ret;
0088 }
0089
0090 static int max96712_write_bulk_value(struct max96712_priv *priv,
0091 unsigned int reg, unsigned int val,
0092 size_t val_count)
0093 {
0094 unsigned int i;
0095 u8 values[4];
0096
0097 for (i = 1; i <= val_count; i++)
0098 values[i - 1] = (val >> ((val_count - i) * 8)) & 0xff;
0099
0100 return max96712_write_bulk(priv, reg, &values, val_count);
0101 }
0102
0103 static void max96712_reset(struct max96712_priv *priv)
0104 {
0105 max96712_update_bits(priv, 0x13, 0x40, 0x40);
0106 msleep(20);
0107 }
0108
0109 static void max96712_mipi_enable(struct max96712_priv *priv, bool enable)
0110 {
0111 if (enable) {
0112 max96712_update_bits(priv, 0x40b, 0x02, 0x02);
0113 max96712_update_bits(priv, 0x8a0, 0x80, 0x80);
0114 } else {
0115 max96712_update_bits(priv, 0x8a0, 0x80, 0x00);
0116 max96712_update_bits(priv, 0x40b, 0x02, 0x00);
0117 }
0118 }
0119
0120 static void max96712_mipi_configure(struct max96712_priv *priv)
0121 {
0122 unsigned int i;
0123 u8 phy5 = 0;
0124
0125 max96712_mipi_enable(priv, false);
0126
0127
0128 max96712_write(priv, 0x8a0, 0x04);
0129
0130
0131
0132
0133 max96712_write(priv, 0x94a, 0xc0);
0134
0135
0136
0137 max96712_write(priv, 0x8a3, 0xe4);
0138
0139
0140 for (i = 0; i < priv->mipi.num_data_lanes + 1; i++)
0141 if (priv->mipi.lane_polarities[i])
0142 phy5 |= BIT(i == 0 ? 5 : i < 3 ? i - 1 : i);
0143 max96712_write(priv, 0x8a5, phy5);
0144
0145
0146 max96712_update_bits(priv, 0x415, 0x3f,
0147 ((MAX96712_DPLL_FREQ / 100) & 0x1f) | BIT(5));
0148 max96712_update_bits(priv, 0x418, 0x3f,
0149 ((MAX96712_DPLL_FREQ / 100) & 0x1f) | BIT(5));
0150
0151
0152 max96712_update_bits(priv, 0x8a2, 0xf0, 0x30);
0153 }
0154
0155 static void max96712_pattern_enable(struct max96712_priv *priv, bool enable)
0156 {
0157 const u32 h_active = 1920;
0158 const u32 h_fp = 88;
0159 const u32 h_sw = 44;
0160 const u32 h_bp = 148;
0161 const u32 h_tot = h_active + h_fp + h_sw + h_bp;
0162
0163 const u32 v_active = 1080;
0164 const u32 v_fp = 4;
0165 const u32 v_sw = 5;
0166 const u32 v_bp = 36;
0167 const u32 v_tot = v_active + v_fp + v_sw + v_bp;
0168
0169 if (!enable) {
0170 max96712_write(priv, 0x1051, 0x00);
0171 return;
0172 }
0173
0174
0175 max96712_write(priv, 0x0009, 0x01);
0176
0177
0178 max96712_write_bulk_value(priv, 0x1052, 0, 3);
0179 max96712_write_bulk_value(priv, 0x1055, v_sw * h_tot, 3);
0180 max96712_write_bulk_value(priv, 0x1058,
0181 (v_active + v_fp + + v_bp) * h_tot, 3);
0182 max96712_write_bulk_value(priv, 0x105b, 0, 3);
0183 max96712_write_bulk_value(priv, 0x105e, h_sw, 2);
0184 max96712_write_bulk_value(priv, 0x1060, h_active + h_fp + h_bp, 2);
0185 max96712_write_bulk_value(priv, 0x1062, v_tot, 2);
0186 max96712_write_bulk_value(priv, 0x1064,
0187 h_tot * (v_sw + v_bp) + (h_sw + h_bp), 3);
0188 max96712_write_bulk_value(priv, 0x1067, h_active, 2);
0189 max96712_write_bulk_value(priv, 0x1069, h_fp + h_sw + h_bp, 2);
0190 max96712_write_bulk_value(priv, 0x106b, v_active, 2);
0191
0192
0193 max96712_write(priv, 0x1050, 0xfb);
0194
0195
0196 if (priv->pattern == MAX96712_PATTERN_CHECKERBOARD) {
0197
0198 max96712_write(priv, 0x1074, 0x3c);
0199 max96712_write(priv, 0x1075, 0x3c);
0200 max96712_write(priv, 0x1076, 0x3c);
0201
0202
0203 max96712_write_bulk_value(priv, 0x106e, 0xfecc00, 3);
0204 max96712_write_bulk_value(priv, 0x1071, 0x006aa7, 3);
0205
0206
0207 max96712_write(priv, 0x1051, 0x10);
0208 } else {
0209
0210 max96712_write(priv, 0x106d, 0x10);
0211
0212
0213 max96712_write(priv, 0x1051, 0x20);
0214 }
0215 }
0216
0217 static int max96712_s_stream(struct v4l2_subdev *sd, int enable)
0218 {
0219 struct max96712_priv *priv = v4l2_get_subdevdata(sd);
0220
0221 if (enable) {
0222 max96712_pattern_enable(priv, true);
0223 max96712_mipi_enable(priv, true);
0224 } else {
0225 max96712_mipi_enable(priv, false);
0226 max96712_pattern_enable(priv, false);
0227 }
0228
0229 return 0;
0230 }
0231
0232 static const struct v4l2_subdev_video_ops max96712_video_ops = {
0233 .s_stream = max96712_s_stream,
0234 };
0235
0236 static int max96712_get_pad_format(struct v4l2_subdev *sd,
0237 struct v4l2_subdev_state *sd_state,
0238 struct v4l2_subdev_format *format)
0239 {
0240 format->format.width = 1920;
0241 format->format.height = 1080;
0242 format->format.code = MEDIA_BUS_FMT_RGB888_1X24;
0243 format->format.field = V4L2_FIELD_NONE;
0244
0245 return 0;
0246 }
0247
0248 static const struct v4l2_subdev_pad_ops max96712_pad_ops = {
0249 .get_fmt = max96712_get_pad_format,
0250 .set_fmt = max96712_get_pad_format,
0251 };
0252
0253 static const struct v4l2_subdev_ops max96712_subdev_ops = {
0254 .video = &max96712_video_ops,
0255 .pad = &max96712_pad_ops,
0256 };
0257
0258 static const char * const max96712_test_pattern[] = {
0259 "Checkerboard",
0260 "Gradient",
0261 };
0262
0263 static int max96712_s_ctrl(struct v4l2_ctrl *ctrl)
0264 {
0265 struct max96712_priv *priv =
0266 container_of(ctrl->handler, struct max96712_priv, ctrl_handler);
0267
0268 switch (ctrl->id) {
0269 case V4L2_CID_TEST_PATTERN:
0270 priv->pattern = ctrl->val ?
0271 MAX96712_PATTERN_GRADIENT :
0272 MAX96712_PATTERN_CHECKERBOARD;
0273 break;
0274 }
0275 return 0;
0276 }
0277
0278 static const struct v4l2_ctrl_ops max96712_ctrl_ops = {
0279 .s_ctrl = max96712_s_ctrl,
0280 };
0281
0282 static int max96712_v4l2_register(struct max96712_priv *priv)
0283 {
0284 long pixel_rate;
0285 int ret;
0286
0287 v4l2_i2c_subdev_init(&priv->sd, priv->client, &max96712_subdev_ops);
0288 priv->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
0289 priv->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
0290
0291 v4l2_ctrl_handler_init(&priv->ctrl_handler, 2);
0292
0293
0294
0295
0296
0297 pixel_rate = MAX96712_DPLL_FREQ / priv->mipi.num_data_lanes * 1000000;
0298 v4l2_ctrl_new_std(&priv->ctrl_handler, NULL, V4L2_CID_PIXEL_RATE,
0299 pixel_rate, pixel_rate, 1, pixel_rate);
0300
0301 v4l2_ctrl_new_std_menu_items(&priv->ctrl_handler, &max96712_ctrl_ops,
0302 V4L2_CID_TEST_PATTERN,
0303 ARRAY_SIZE(max96712_test_pattern) - 1,
0304 0, 0, max96712_test_pattern);
0305
0306 priv->sd.ctrl_handler = &priv->ctrl_handler;
0307 ret = priv->ctrl_handler.error;
0308 if (ret)
0309 goto error;
0310
0311 priv->pads[0].flags = MEDIA_PAD_FL_SOURCE;
0312 ret = media_entity_pads_init(&priv->sd.entity, 1, priv->pads);
0313 if (ret)
0314 goto error;
0315
0316 v4l2_set_subdevdata(&priv->sd, priv);
0317
0318 ret = v4l2_async_register_subdev(&priv->sd);
0319 if (ret < 0) {
0320 dev_err(&priv->client->dev, "Unable to register subdevice\n");
0321 goto error;
0322 }
0323
0324 return 0;
0325 error:
0326 v4l2_ctrl_handler_free(&priv->ctrl_handler);
0327
0328 return ret;
0329 }
0330
0331 static int max96712_parse_dt(struct max96712_priv *priv)
0332 {
0333 struct fwnode_handle *ep;
0334 struct v4l2_fwnode_endpoint v4l2_ep = {
0335 .bus_type = V4L2_MBUS_CSI2_DPHY
0336 };
0337 int ret;
0338
0339 ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(&priv->client->dev), 4,
0340 0, 0);
0341 if (!ep) {
0342 dev_err(&priv->client->dev, "Not connected to subdevice\n");
0343 return -EINVAL;
0344 }
0345
0346 ret = v4l2_fwnode_endpoint_parse(ep, &v4l2_ep);
0347 fwnode_handle_put(ep);
0348 if (ret) {
0349 dev_err(&priv->client->dev, "Could not parse v4l2 endpoint\n");
0350 return -EINVAL;
0351 }
0352
0353 if (v4l2_ep.bus.mipi_csi2.num_data_lanes != 4) {
0354 dev_err(&priv->client->dev, "Only 4 data lanes supported\n");
0355 return -EINVAL;
0356 }
0357
0358 priv->mipi = v4l2_ep.bus.mipi_csi2;
0359
0360 return 0;
0361 }
0362
0363 static const struct regmap_config max96712_i2c_regmap = {
0364 .reg_bits = 16,
0365 .val_bits = 8,
0366 .max_register = 0x1f00,
0367 };
0368
0369 static int max96712_probe(struct i2c_client *client)
0370 {
0371 struct max96712_priv *priv;
0372 int ret;
0373
0374 priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
0375 if (!priv)
0376 return -ENOMEM;
0377
0378 priv->client = client;
0379 i2c_set_clientdata(client, priv);
0380
0381 priv->regmap = devm_regmap_init_i2c(client, &max96712_i2c_regmap);
0382 if (IS_ERR(priv->regmap))
0383 return PTR_ERR(priv->regmap);
0384
0385 priv->gpiod_pwdn = devm_gpiod_get_optional(&client->dev, "enable",
0386 GPIOD_OUT_HIGH);
0387 if (IS_ERR(priv->gpiod_pwdn))
0388 return PTR_ERR(priv->gpiod_pwdn);
0389
0390 gpiod_set_consumer_name(priv->gpiod_pwdn, "max96712-pwdn");
0391 gpiod_set_value_cansleep(priv->gpiod_pwdn, 1);
0392
0393 if (priv->gpiod_pwdn)
0394 usleep_range(4000, 5000);
0395
0396 if (max96712_read(priv, 0x4a) != MAX96712_ID)
0397 return -ENODEV;
0398
0399 max96712_reset(priv);
0400
0401 ret = max96712_parse_dt(priv);
0402 if (ret)
0403 return ret;
0404
0405 max96712_mipi_configure(priv);
0406
0407 return max96712_v4l2_register(priv);
0408 }
0409
0410 static int max96712_remove(struct i2c_client *client)
0411 {
0412 struct max96712_priv *priv = i2c_get_clientdata(client);
0413
0414 v4l2_async_unregister_subdev(&priv->sd);
0415
0416 gpiod_set_value_cansleep(priv->gpiod_pwdn, 0);
0417
0418 return 0;
0419 }
0420
0421 static const struct of_device_id max96712_of_table[] = {
0422 { .compatible = "maxim,max96712" },
0423 { },
0424 };
0425 MODULE_DEVICE_TABLE(of, max96712_of_table);
0426
0427 static struct i2c_driver max96712_i2c_driver = {
0428 .driver = {
0429 .name = "max96712",
0430 .of_match_table = of_match_ptr(max96712_of_table),
0431 },
0432 .probe_new = max96712_probe,
0433 .remove = max96712_remove,
0434 };
0435
0436 module_i2c_driver(max96712_i2c_driver);
0437
0438 MODULE_DESCRIPTION("Maxim MAX96712 Quad GMSL2 Deserializer Driver");
0439 MODULE_AUTHOR("Niklas Söderlund <niklas.soderlund@ragnatech.se>");
0440 MODULE_LICENSE("GPL");