.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
---|
1 | 2 | /* |
---|
2 | 3 | * imx274.c - IMX274 CMOS Image Sensor driver |
---|
3 | 4 | * |
---|
.. | .. |
---|
6 | 7 | * Leon Luo <leonl@leopardimaging.com> |
---|
7 | 8 | * Edwin Zou <edwinz@leopardimaging.com> |
---|
8 | 9 | * Luca Ceresoli <luca@lucaceresoli.net> |
---|
9 | | - * |
---|
10 | | - * This program is free software; you can redistribute it and/or modify it |
---|
11 | | - * under the terms and conditions of the GNU General Public License, |
---|
12 | | - * version 2, as published by the Free Software Foundation. |
---|
13 | | - * |
---|
14 | | - * This program is distributed in the hope it will be useful, but WITHOUT |
---|
15 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
---|
16 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
---|
17 | | - * more details. |
---|
18 | | - * |
---|
19 | | - * You should have received a copy of the GNU General Public License |
---|
20 | | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
---|
21 | 10 | */ |
---|
22 | 11 | |
---|
23 | 12 | #include <linux/clk.h> |
---|
.. | .. |
---|
76 | 65 | */ |
---|
77 | 66 | #define IMX274_MIN_EXPOSURE_TIME (4 * 260 / 72) |
---|
78 | 67 | |
---|
79 | | -#define IMX274_DEFAULT_MODE IMX274_BINNING_OFF |
---|
| 68 | +#define IMX274_DEFAULT_BINNING IMX274_BINNING_OFF |
---|
80 | 69 | #define IMX274_MAX_WIDTH (3840) |
---|
81 | 70 | #define IMX274_MAX_HEIGHT (2160) |
---|
82 | 71 | #define IMX274_MAX_FRAME_RATE (120) |
---|
.. | .. |
---|
178 | 167 | * @nocpiop: Number of clocks per internal offset period (see "Integration Time |
---|
179 | 168 | * in Each Readout Drive Mode (CSI-2)" in the datasheet) |
---|
180 | 169 | */ |
---|
181 | | -struct imx274_frmfmt { |
---|
| 170 | +struct imx274_mode { |
---|
182 | 171 | const struct reg_8 *init_regs; |
---|
183 | 172 | unsigned int bin_ratio; |
---|
184 | 173 | int min_frame_len; |
---|
.. | .. |
---|
218 | 207 | "Vertical Stripe (555h / 000h)", |
---|
219 | 208 | "Vertical Stripe (000h / FFFh)", |
---|
220 | 209 | "Vertical Stripe (FFFh / 000h)", |
---|
221 | | - "Horizontal Color Bars", |
---|
222 | 210 | "Vertical Color Bars", |
---|
| 211 | + "Horizontal Color Bars", |
---|
223 | 212 | }; |
---|
224 | 213 | |
---|
225 | 214 | /* |
---|
.. | .. |
---|
349 | 338 | */ |
---|
350 | 339 | static const struct reg_8 imx274_start_1[] = { |
---|
351 | 340 | {IMX274_STANDBY_REG, 0x12}, |
---|
352 | | - {IMX274_TABLE_END, 0x00} |
---|
353 | | -}; |
---|
354 | 341 | |
---|
355 | | -/* |
---|
356 | | - * imx274 second step register configuration for |
---|
357 | | - * starting stream |
---|
358 | | - */ |
---|
359 | | -static const struct reg_8 imx274_start_2[] = { |
---|
360 | | - {0x3120, 0xF0}, /* clock settings */ |
---|
361 | | - {0x3121, 0x00}, /* clock settings */ |
---|
362 | | - {0x3122, 0x02}, /* clock settings */ |
---|
363 | | - {0x3129, 0x9C}, /* clock settings */ |
---|
364 | | - {0x312A, 0x02}, /* clock settings */ |
---|
365 | | - {0x312D, 0x02}, /* clock settings */ |
---|
| 342 | + /* PLRD: clock settings */ |
---|
| 343 | + {0x3120, 0xF0}, |
---|
| 344 | + {0x3121, 0x00}, |
---|
| 345 | + {0x3122, 0x02}, |
---|
| 346 | + {0x3129, 0x9C}, |
---|
| 347 | + {0x312A, 0x02}, |
---|
| 348 | + {0x312D, 0x02}, |
---|
366 | 349 | |
---|
367 | 350 | {0x310B, 0x00}, |
---|
368 | 351 | |
---|
.. | .. |
---|
407 | 390 | }; |
---|
408 | 391 | |
---|
409 | 392 | /* |
---|
410 | | - * imx274 third step register configuration for |
---|
| 393 | + * imx274 second step register configuration for |
---|
411 | 394 | * starting stream |
---|
412 | 395 | */ |
---|
413 | | -static const struct reg_8 imx274_start_3[] = { |
---|
| 396 | +static const struct reg_8 imx274_start_2[] = { |
---|
414 | 397 | {IMX274_STANDBY_REG, 0x00}, |
---|
415 | 398 | {0x303E, 0x02}, /* SYS_MODE = 2 */ |
---|
416 | 399 | {IMX274_TABLE_END, 0x00} |
---|
417 | 400 | }; |
---|
418 | 401 | |
---|
419 | 402 | /* |
---|
420 | | - * imx274 forth step register configuration for |
---|
| 403 | + * imx274 third step register configuration for |
---|
421 | 404 | * starting stream |
---|
422 | 405 | */ |
---|
423 | | -static const struct reg_8 imx274_start_4[] = { |
---|
| 406 | +static const struct reg_8 imx274_start_3[] = { |
---|
424 | 407 | {0x30F4, 0x00}, |
---|
425 | | - {0x3018, 0xA2}, /* XHS VHS OUTUPT */ |
---|
| 408 | + {0x3018, 0xA2}, /* XHS VHS OUTPUT */ |
---|
426 | 409 | {IMX274_TABLE_END, 0x00} |
---|
427 | 410 | }; |
---|
428 | 411 | |
---|
429 | 412 | /* |
---|
430 | | - * imx274 register configuration for stoping stream |
---|
| 413 | + * imx274 register configuration for stopping stream |
---|
431 | 414 | */ |
---|
432 | 415 | static const struct reg_8 imx274_stop[] = { |
---|
433 | 416 | {IMX274_STANDBY_REG, 0x01}, |
---|
.. | .. |
---|
459 | 442 | }; |
---|
460 | 443 | |
---|
461 | 444 | /* nocpiop happens to be the same number for the implemented modes */ |
---|
462 | | -static const struct imx274_frmfmt imx274_formats[] = { |
---|
| 445 | +static const struct imx274_mode imx274_modes[] = { |
---|
463 | 446 | { |
---|
464 | 447 | /* mode 1, 4K */ |
---|
465 | 448 | .bin_ratio = 1, |
---|
.. | .. |
---|
532 | 515 | struct regmap *regmap; |
---|
533 | 516 | struct gpio_desc *reset_gpio; |
---|
534 | 517 | struct mutex lock; /* mutex lock for operations */ |
---|
535 | | - const struct imx274_frmfmt *mode; |
---|
| 518 | + const struct imx274_mode *mode; |
---|
536 | 519 | }; |
---|
537 | 520 | |
---|
538 | 521 | #define IMX274_ROUND(dim, step, flags) \ |
---|
.. | .. |
---|
634 | 617 | return 0; |
---|
635 | 618 | } |
---|
636 | 619 | |
---|
637 | | -static inline int imx274_read_reg(struct stimx274 *priv, u16 addr, u8 *val) |
---|
638 | | -{ |
---|
639 | | - unsigned int uint_val; |
---|
640 | | - int err; |
---|
641 | | - |
---|
642 | | - err = regmap_read(priv->regmap, addr, &uint_val); |
---|
643 | | - if (err) |
---|
644 | | - dev_err(&priv->client->dev, |
---|
645 | | - "%s : i2c read failed, addr = %x\n", __func__, addr); |
---|
646 | | - else |
---|
647 | | - dev_dbg(&priv->client->dev, |
---|
648 | | - "%s : addr 0x%x, val=0x%x\n", __func__, |
---|
649 | | - addr, uint_val); |
---|
650 | | - |
---|
651 | | - *val = uint_val; |
---|
652 | | - return err; |
---|
653 | | -} |
---|
654 | | - |
---|
655 | 620 | static inline int imx274_write_reg(struct stimx274 *priv, u16 addr, u8 val) |
---|
656 | 621 | { |
---|
657 | 622 | int err; |
---|
.. | .. |
---|
669 | 634 | } |
---|
670 | 635 | |
---|
671 | 636 | /** |
---|
| 637 | + * Read a multibyte register. |
---|
| 638 | + * |
---|
| 639 | + * Uses a bulk read where possible. |
---|
| 640 | + * |
---|
| 641 | + * @priv: Pointer to device structure |
---|
| 642 | + * @addr: Address of the LSB register. Other registers must be |
---|
| 643 | + * consecutive, least-to-most significant. |
---|
| 644 | + * @val: Pointer to store the register value (cpu endianness) |
---|
| 645 | + * @nbytes: Number of bytes to read (range: [1..3]). |
---|
| 646 | + * Other bytes are zet to 0. |
---|
| 647 | + * |
---|
| 648 | + * Return: 0 on success, errors otherwise |
---|
| 649 | + */ |
---|
| 650 | +static int imx274_read_mbreg(struct stimx274 *priv, u16 addr, u32 *val, |
---|
| 651 | + size_t nbytes) |
---|
| 652 | +{ |
---|
| 653 | + __le32 val_le = 0; |
---|
| 654 | + int err; |
---|
| 655 | + |
---|
| 656 | + err = regmap_bulk_read(priv->regmap, addr, &val_le, nbytes); |
---|
| 657 | + if (err) { |
---|
| 658 | + dev_err(&priv->client->dev, |
---|
| 659 | + "%s : i2c bulk read failed, %x (%zu bytes)\n", |
---|
| 660 | + __func__, addr, nbytes); |
---|
| 661 | + } else { |
---|
| 662 | + *val = le32_to_cpu(val_le); |
---|
| 663 | + dev_dbg(&priv->client->dev, |
---|
| 664 | + "%s : addr 0x%x, val=0x%x (%zu bytes)\n", |
---|
| 665 | + __func__, addr, *val, nbytes); |
---|
| 666 | + } |
---|
| 667 | + |
---|
| 668 | + return err; |
---|
| 669 | +} |
---|
| 670 | + |
---|
| 671 | +/** |
---|
672 | 672 | * Write a multibyte register. |
---|
673 | 673 | * |
---|
674 | 674 | * Uses a bulk write where possible. |
---|
.. | .. |
---|
677 | 677 | * @addr: Address of the LSB register. Other registers must be |
---|
678 | 678 | * consecutive, least-to-most significant. |
---|
679 | 679 | * @val: Value to be written to the register (cpu endianness) |
---|
680 | | - * @nbytes: Number of bits to write (range: [1..3]) |
---|
| 680 | + * @nbytes: Number of bytes to write (range: [1..3]) |
---|
681 | 681 | */ |
---|
682 | 682 | static int imx274_write_mbreg(struct stimx274 *priv, u16 addr, u32 val, |
---|
683 | 683 | size_t nbytes) |
---|
.. | .. |
---|
711 | 711 | if (err) |
---|
712 | 712 | return err; |
---|
713 | 713 | |
---|
714 | | - err = imx274_write_table(priv, imx274_start_2); |
---|
715 | | - if (err) |
---|
716 | | - return err; |
---|
717 | | - |
---|
718 | 714 | err = imx274_write_table(priv, priv->mode->init_regs); |
---|
719 | 715 | |
---|
720 | 716 | return err; |
---|
.. | .. |
---|
736 | 732 | * give it 1 extra ms for margin |
---|
737 | 733 | */ |
---|
738 | 734 | msleep_range(11); |
---|
739 | | - err = imx274_write_table(priv, imx274_start_3); |
---|
| 735 | + err = imx274_write_table(priv, imx274_start_2); |
---|
740 | 736 | if (err) |
---|
741 | 737 | return err; |
---|
742 | 738 | |
---|
.. | .. |
---|
746 | 742 | * give it 1 extra ms for margin |
---|
747 | 743 | */ |
---|
748 | 744 | msleep_range(8); |
---|
749 | | - err = imx274_write_table(priv, imx274_start_4); |
---|
| 745 | + err = imx274_write_table(priv, imx274_start_3); |
---|
750 | 746 | if (err) |
---|
751 | 747 | return err; |
---|
752 | 748 | |
---|
.. | .. |
---|
884 | 880 | const struct v4l2_rect *cur_crop; |
---|
885 | 881 | struct v4l2_mbus_framefmt *tgt_fmt; |
---|
886 | 882 | unsigned int i; |
---|
887 | | - const struct imx274_frmfmt *best_mode = &imx274_formats[0]; |
---|
| 883 | + const struct imx274_mode *best_mode = &imx274_modes[0]; |
---|
888 | 884 | int best_goodness = INT_MIN; |
---|
889 | 885 | |
---|
890 | 886 | if (which == V4L2_SUBDEV_FORMAT_TRY) { |
---|
.. | .. |
---|
895 | 891 | tgt_fmt = &imx274->format; |
---|
896 | 892 | } |
---|
897 | 893 | |
---|
898 | | - for (i = 0; i < ARRAY_SIZE(imx274_formats); i++) { |
---|
899 | | - unsigned int ratio = imx274_formats[i].bin_ratio; |
---|
| 894 | + for (i = 0; i < ARRAY_SIZE(imx274_modes); i++) { |
---|
| 895 | + unsigned int ratio = imx274_modes[i].bin_ratio; |
---|
900 | 896 | |
---|
901 | 897 | int goodness = imx274_binning_goodness( |
---|
902 | 898 | imx274, |
---|
.. | .. |
---|
906 | 902 | |
---|
907 | 903 | if (goodness >= best_goodness) { |
---|
908 | 904 | best_goodness = goodness; |
---|
909 | | - best_mode = &imx274_formats[i]; |
---|
| 905 | + best_mode = &imx274_modes[i]; |
---|
910 | 906 | } |
---|
911 | 907 | } |
---|
912 | 908 | |
---|
.. | .. |
---|
1328 | 1324 | |
---|
1329 | 1325 | dev_dbg(&imx274->client->dev, "%s : %s, mode index = %td\n", __func__, |
---|
1330 | 1326 | on ? "Stream Start" : "Stream Stop", |
---|
1331 | | - imx274->mode - &imx274_formats[0]); |
---|
| 1327 | + imx274->mode - &imx274_modes[0]); |
---|
1332 | 1328 | |
---|
1333 | 1329 | mutex_lock(&imx274->lock); |
---|
1334 | 1330 | |
---|
.. | .. |
---|
1392 | 1388 | static int imx274_get_frame_length(struct stimx274 *priv, u32 *val) |
---|
1393 | 1389 | { |
---|
1394 | 1390 | int err; |
---|
1395 | | - u16 svr; |
---|
| 1391 | + u32 svr; |
---|
1396 | 1392 | u32 vmax; |
---|
1397 | | - u8 reg_val[3]; |
---|
1398 | 1393 | |
---|
1399 | | - /* svr */ |
---|
1400 | | - err = imx274_read_reg(priv, IMX274_SVR_REG_LSB, ®_val[0]); |
---|
| 1394 | + err = imx274_read_mbreg(priv, IMX274_SVR_REG_LSB, &svr, 2); |
---|
1401 | 1395 | if (err) |
---|
1402 | 1396 | goto fail; |
---|
1403 | 1397 | |
---|
1404 | | - err = imx274_read_reg(priv, IMX274_SVR_REG_MSB, ®_val[1]); |
---|
| 1398 | + err = imx274_read_mbreg(priv, IMX274_VMAX_REG_3, &vmax, 3); |
---|
1405 | 1399 | if (err) |
---|
1406 | 1400 | goto fail; |
---|
1407 | | - |
---|
1408 | | - svr = (reg_val[1] << IMX274_SHIFT_8_BITS) + reg_val[0]; |
---|
1409 | | - |
---|
1410 | | - /* vmax */ |
---|
1411 | | - err = imx274_read_reg(priv, IMX274_VMAX_REG_3, ®_val[0]); |
---|
1412 | | - if (err) |
---|
1413 | | - goto fail; |
---|
1414 | | - |
---|
1415 | | - err = imx274_read_reg(priv, IMX274_VMAX_REG_2, ®_val[1]); |
---|
1416 | | - if (err) |
---|
1417 | | - goto fail; |
---|
1418 | | - |
---|
1419 | | - err = imx274_read_reg(priv, IMX274_VMAX_REG_1, ®_val[2]); |
---|
1420 | | - if (err) |
---|
1421 | | - goto fail; |
---|
1422 | | - |
---|
1423 | | - vmax = ((reg_val[2] & IMX274_MASK_LSB_3_BITS) << IMX274_SHIFT_16_BITS) |
---|
1424 | | - + (reg_val[1] << IMX274_SHIFT_8_BITS) + reg_val[0]; |
---|
1425 | 1401 | |
---|
1426 | 1402 | *val = vmax * (svr + 1); |
---|
1427 | 1403 | |
---|
.. | .. |
---|
1603 | 1579 | static int imx274_set_exposure(struct stimx274 *priv, int val) |
---|
1604 | 1580 | { |
---|
1605 | 1581 | int err; |
---|
1606 | | - u16 hmax; |
---|
1607 | | - u8 reg_val[2]; |
---|
| 1582 | + u32 hmax; |
---|
1608 | 1583 | u32 coarse_time; /* exposure time in unit of line (HMAX)*/ |
---|
1609 | 1584 | |
---|
1610 | 1585 | dev_dbg(&priv->client->dev, |
---|
.. | .. |
---|
1612 | 1587 | |
---|
1613 | 1588 | /* step 1: convert input exposure_time (val) into number of 1[HMAX] */ |
---|
1614 | 1589 | |
---|
1615 | | - /* obtain HMAX value */ |
---|
1616 | | - err = imx274_read_reg(priv, IMX274_HMAX_REG_LSB, ®_val[0]); |
---|
| 1590 | + err = imx274_read_mbreg(priv, IMX274_HMAX_REG_LSB, &hmax, 2); |
---|
1617 | 1591 | if (err) |
---|
1618 | 1592 | goto fail; |
---|
1619 | | - err = imx274_read_reg(priv, IMX274_HMAX_REG_MSB, ®_val[1]); |
---|
1620 | | - if (err) |
---|
1621 | | - goto fail; |
---|
1622 | | - hmax = (reg_val[1] << IMX274_SHIFT_8_BITS) + reg_val[0]; |
---|
| 1593 | + |
---|
1623 | 1594 | if (hmax == 0) { |
---|
1624 | 1595 | err = -EINVAL; |
---|
1625 | 1596 | goto fail; |
---|
.. | .. |
---|
1754 | 1725 | { |
---|
1755 | 1726 | int err; |
---|
1756 | 1727 | u32 frame_length, req_frame_rate; |
---|
1757 | | - u16 svr; |
---|
1758 | | - u16 hmax; |
---|
1759 | | - u8 reg_val[2]; |
---|
| 1728 | + u32 svr; |
---|
| 1729 | + u32 hmax; |
---|
1760 | 1730 | |
---|
1761 | 1731 | dev_dbg(&priv->client->dev, "%s: input frame interval = %d / %d", |
---|
1762 | 1732 | __func__, frame_interval.numerator, |
---|
.. | .. |
---|
1784 | 1754 | * frame_length (i.e. VMAX) = (frame_interval) x 72M /(SVR+1) / HMAX |
---|
1785 | 1755 | */ |
---|
1786 | 1756 | |
---|
1787 | | - /* SVR */ |
---|
1788 | | - err = imx274_read_reg(priv, IMX274_SVR_REG_LSB, ®_val[0]); |
---|
| 1757 | + err = imx274_read_mbreg(priv, IMX274_SVR_REG_LSB, &svr, 2); |
---|
1789 | 1758 | if (err) |
---|
1790 | 1759 | goto fail; |
---|
1791 | | - err = imx274_read_reg(priv, IMX274_SVR_REG_MSB, ®_val[1]); |
---|
1792 | | - if (err) |
---|
1793 | | - goto fail; |
---|
1794 | | - svr = (reg_val[1] << IMX274_SHIFT_8_BITS) + reg_val[0]; |
---|
| 1760 | + |
---|
1795 | 1761 | dev_dbg(&priv->client->dev, |
---|
1796 | 1762 | "%s : register SVR = %d\n", __func__, svr); |
---|
1797 | 1763 | |
---|
1798 | | - /* HMAX */ |
---|
1799 | | - err = imx274_read_reg(priv, IMX274_HMAX_REG_LSB, ®_val[0]); |
---|
| 1764 | + err = imx274_read_mbreg(priv, IMX274_HMAX_REG_LSB, &hmax, 2); |
---|
1800 | 1765 | if (err) |
---|
1801 | 1766 | goto fail; |
---|
1802 | | - err = imx274_read_reg(priv, IMX274_HMAX_REG_MSB, ®_val[1]); |
---|
1803 | | - if (err) |
---|
1804 | | - goto fail; |
---|
1805 | | - hmax = (reg_val[1] << IMX274_SHIFT_8_BITS) + reg_val[0]; |
---|
| 1767 | + |
---|
1806 | 1768 | dev_dbg(&priv->client->dev, |
---|
1807 | 1769 | "%s : register HMAX = %d\n", __func__, hmax); |
---|
1808 | 1770 | |
---|
.. | .. |
---|
1861 | 1823 | }; |
---|
1862 | 1824 | MODULE_DEVICE_TABLE(i2c, imx274_id); |
---|
1863 | 1825 | |
---|
1864 | | -static int imx274_probe(struct i2c_client *client, |
---|
1865 | | - const struct i2c_device_id *id) |
---|
| 1826 | +static int imx274_probe(struct i2c_client *client) |
---|
1866 | 1827 | { |
---|
1867 | 1828 | struct v4l2_subdev *sd; |
---|
1868 | 1829 | struct stimx274 *imx274; |
---|
.. | .. |
---|
1876 | 1837 | mutex_init(&imx274->lock); |
---|
1877 | 1838 | |
---|
1878 | 1839 | /* initialize format */ |
---|
1879 | | - imx274->mode = &imx274_formats[IMX274_DEFAULT_MODE]; |
---|
| 1840 | + imx274->mode = &imx274_modes[IMX274_DEFAULT_BINNING]; |
---|
1880 | 1841 | imx274->crop.width = IMX274_MAX_WIDTH; |
---|
1881 | 1842 | imx274->crop.height = IMX274_MAX_HEIGHT; |
---|
1882 | 1843 | imx274->format.width = imx274->crop.width / imx274->mode->bin_ratio; |
---|
.. | .. |
---|
1900 | 1861 | imx274->client = client; |
---|
1901 | 1862 | sd = &imx274->sd; |
---|
1902 | 1863 | v4l2_i2c_subdev_init(sd, client, &imx274_subdev_ops); |
---|
1903 | | - strlcpy(sd->name, DRIVER_NAME, sizeof(sd->name)); |
---|
1904 | 1864 | sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS; |
---|
1905 | 1865 | |
---|
1906 | 1866 | /* initialize subdev media pad */ |
---|
.. | .. |
---|
1927 | 1887 | imx274_reset(imx274, 1); |
---|
1928 | 1888 | |
---|
1929 | 1889 | /* initialize controls */ |
---|
1930 | | - ret = v4l2_ctrl_handler_init(&imx274->ctrls.handler, 2); |
---|
| 1890 | + ret = v4l2_ctrl_handler_init(&imx274->ctrls.handler, 4); |
---|
1931 | 1891 | if (ret < 0) { |
---|
1932 | 1892 | dev_err(&client->dev, |
---|
1933 | 1893 | "%s : ctrl handler init Failed\n", __func__); |
---|
.. | .. |
---|
2025 | 1985 | .name = DRIVER_NAME, |
---|
2026 | 1986 | .of_match_table = imx274_of_id_table, |
---|
2027 | 1987 | }, |
---|
2028 | | - .probe = imx274_probe, |
---|
| 1988 | + .probe_new = imx274_probe, |
---|
2029 | 1989 | .remove = imx274_remove, |
---|
2030 | 1990 | .id_table = imx274_id, |
---|
2031 | 1991 | }; |
---|