Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[media] mt9t001: Add regulator support

The sensor needs two power supplies, VAA and VDD. Require a regulator
for each of them.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>

authored by

Laurent Pinchart and committed by
Mauro Carvalho Chehab
b2b3593e e68084c6

+156 -50
+156 -50
drivers/media/i2c/mt9t001.c
··· 13 13 */ 14 14 15 15 #include <linux/i2c.h> 16 - #include <linux/module.h> 17 16 #include <linux/log2.h> 17 + #include <linux/module.h> 18 + #include <linux/regulator/consumer.h> 18 19 #include <linux/slab.h> 19 20 #include <linux/videodev2.h> 20 21 #include <linux/v4l2-mediabus.h> ··· 56 55 #define MT9T001_OUTPUT_CONTROL_SYNC (1 << 0) 57 56 #define MT9T001_OUTPUT_CONTROL_CHIP_ENABLE (1 << 1) 58 57 #define MT9T001_OUTPUT_CONTROL_TEST_DATA (1 << 6) 58 + #define MT9T001_OUTPUT_CONTROL_DEF 0x0002 59 59 #define MT9T001_SHUTTER_WIDTH_HIGH 0x08 60 60 #define MT9T001_SHUTTER_WIDTH_LOW 0x09 61 61 #define MT9T001_SHUTTER_WIDTH_MIN 1 ··· 118 116 struct v4l2_subdev subdev; 119 117 struct media_pad pad; 120 118 119 + struct regulator_bulk_data regulators[2]; 120 + 121 + struct mutex power_lock; /* lock to protect power_count */ 122 + int power_count; 123 + 121 124 struct v4l2_mbus_framefmt format; 122 125 struct v4l2_rect crop; 123 126 ··· 166 159 return 0; 167 160 } 168 161 162 + static int mt9t001_reset(struct mt9t001 *mt9t001) 163 + { 164 + struct i2c_client *client = v4l2_get_subdevdata(&mt9t001->subdev); 165 + int ret; 166 + 167 + /* Reset the chip and stop data read out */ 168 + ret = mt9t001_write(client, MT9T001_RESET, 1); 169 + if (ret < 0) 170 + return ret; 171 + 172 + ret = mt9t001_write(client, MT9T001_RESET, 0); 173 + if (ret < 0) 174 + return ret; 175 + 176 + mt9t001->output_control = MT9T001_OUTPUT_CONTROL_DEF; 177 + 178 + return mt9t001_set_output_control(mt9t001, 179 + MT9T001_OUTPUT_CONTROL_CHIP_ENABLE, 180 + 0); 181 + } 182 + 183 + static int mt9t001_power_on(struct mt9t001 *mt9t001) 184 + { 185 + /* Bring up the supplies */ 186 + return regulator_bulk_enable(ARRAY_SIZE(mt9t001->regulators), 187 + mt9t001->regulators); 188 + } 189 + 190 + static void mt9t001_power_off(struct mt9t001 *mt9t001) 191 + { 192 + regulator_bulk_disable(ARRAY_SIZE(mt9t001->regulators), 193 + mt9t001->regulators); 194 + 195 + static int __mt9t001_set_power(struct mt9t001 *mt9t001, bool on) 196 + { 197 + struct i2c_client *client = v4l2_get_subdevdata(&mt9t001->subdev); 198 + int ret; 199 + 200 + if (!on) { 201 + mt9t001_power_off(mt9t001); 202 + return 0; 203 + } 204 + 205 + ret = mt9t001_power_on(mt9t001); 206 + if (ret < 0) 207 + return ret; 208 + 209 + ret = mt9t001_reset(mt9t001); 210 + if (ret < 0) { 211 + dev_err(&client->dev, "Failed to reset the camera\n"); 212 + return ret; 213 + } 214 + 215 + return v4l2_ctrl_handler_setup(&mt9t001->ctrls); 216 + } 217 + 169 218 /* ----------------------------------------------------------------------------- 170 219 * V4L2 subdev video operations 171 220 */ ··· 258 195 { 259 196 const u16 mode = MT9T001_OUTPUT_CONTROL_CHIP_ENABLE; 260 197 struct i2c_client *client = v4l2_get_subdevdata(subdev); 198 + struct mt9t001_platform_data *pdata = client->dev.platform_data; 261 199 struct mt9t001 *mt9t001 = to_mt9t001(subdev); 262 200 struct v4l2_mbus_framefmt *format = &mt9t001->format; 263 201 struct v4l2_rect *crop = &mt9t001->crop; ··· 268 204 269 205 if (!enable) 270 206 return mt9t001_set_output_control(mt9t001, mode, 0); 207 + 208 + /* Configure the pixel clock polarity */ 209 + if (pdata->clk_pol) { 210 + ret = mt9t001_write(client, MT9T001_PIXEL_CLOCK, 211 + MT9T001_PIXEL_CLOCK_INVERT); 212 + if (ret < 0) 213 + return ret; 214 + } 271 215 272 216 /* Configure the window size and row/column bin */ 273 217 hratio = DIV_ROUND_CLOSEST(crop->width, format->width); ··· 702 630 }; 703 631 704 632 /* ----------------------------------------------------------------------------- 633 + * V4L2 subdev core operations 634 + */ 635 + 636 + static int mt9t001_set_power(struct v4l2_subdev *subdev, int on) 637 + { 638 + struct mt9t001 *mt9t001 = to_mt9t001(subdev); 639 + int ret = 0; 640 + 641 + mutex_lock(&mt9t001->power_lock); 642 + 643 + /* If the power count is modified from 0 to != 0 or from != 0 to 0, 644 + * update the power state. 645 + */ 646 + if (mt9t001->power_count == !on) { 647 + ret = __mt9t001_set_power(mt9t001, !!on); 648 + if (ret < 0) 649 + goto out; 650 + } 651 + 652 + /* Update the power count. */ 653 + mt9t001->power_count += on ? 1 : -1; 654 + WARN_ON(mt9t001->power_count < 0); 655 + 656 + out: 657 + mutex_unlock(&mt9t001->power_lock); 658 + return ret; 659 + } 660 + 661 + /* ----------------------------------------------------------------------------- 705 662 * V4L2 subdev internal operations 706 663 */ 664 + 665 + static int mt9t001_registered(struct v4l2_subdev *subdev) 666 + { 667 + struct i2c_client *client = v4l2_get_subdevdata(subdev); 668 + struct mt9t001 *mt9t001 = to_mt9t001(subdev); 669 + s32 data; 670 + int ret; 671 + 672 + ret = mt9t001_power_on(mt9t001); 673 + if (ret < 0) { 674 + dev_err(&client->dev, "MT9T001 power up failed\n"); 675 + return ret; 676 + } 677 + 678 + /* Read out the chip version register */ 679 + data = mt9t001_read(client, MT9T001_CHIP_VERSION); 680 + mt9t001_power_off(mt9t001); 681 + 682 + if (data != MT9T001_CHIP_ID) { 683 + dev_err(&client->dev, 684 + "MT9T001 not detected, wrong version 0x%04x\n", data); 685 + return -ENODEV; 686 + } 687 + 688 + dev_info(&client->dev, "MT9T001 detected at address 0x%02x\n", 689 + client->addr); 690 + 691 + return 0; 692 + } 707 693 708 694 static int mt9t001_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh) 709 695 { ··· 781 651 format->field = V4L2_FIELD_NONE; 782 652 format->colorspace = V4L2_COLORSPACE_SRGB; 783 653 784 - return 0; 654 + return mt9t001_set_power(subdev, 1); 785 655 } 656 + 657 + static int mt9t001_close(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh) 658 + { 659 + return mt9t001_set_power(subdev, 0); 660 + } 661 + 662 + static struct v4l2_subdev_core_ops mt9t001_subdev_core_ops = { 663 + .s_power = mt9t001_set_power, 664 + }; 786 665 787 666 static struct v4l2_subdev_video_ops mt9t001_subdev_video_ops = { 788 667 .s_stream = mt9t001_s_stream, ··· 807 668 }; 808 669 809 670 static struct v4l2_subdev_ops mt9t001_subdev_ops = { 671 + .core = &mt9t001_subdev_core_ops, 810 672 .video = &mt9t001_subdev_video_ops, 811 673 .pad = &mt9t001_subdev_pad_ops, 812 674 }; 813 675 814 676 static struct v4l2_subdev_internal_ops mt9t001_subdev_internal_ops = { 677 + .registered = mt9t001_registered, 815 678 .open = mt9t001_open, 679 + .close = mt9t001_close, 816 680 }; 817 - 818 - static int mt9t001_video_probe(struct i2c_client *client) 819 - { 820 - struct mt9t001_platform_data *pdata = client->dev.platform_data; 821 - s32 data; 822 - int ret; 823 - 824 - dev_info(&client->dev, "Probing MT9T001 at address 0x%02x\n", 825 - client->addr); 826 - 827 - /* Reset the chip and stop data read out */ 828 - ret = mt9t001_write(client, MT9T001_RESET, 1); 829 - if (ret < 0) 830 - return ret; 831 - 832 - ret = mt9t001_write(client, MT9T001_RESET, 0); 833 - if (ret < 0) 834 - return ret; 835 - 836 - ret = mt9t001_write(client, MT9T001_OUTPUT_CONTROL, 0); 837 - if (ret < 0) 838 - return ret; 839 - 840 - /* Configure the pixel clock polarity */ 841 - if (pdata->clk_pol) { 842 - ret = mt9t001_write(client, MT9T001_PIXEL_CLOCK, 843 - MT9T001_PIXEL_CLOCK_INVERT); 844 - if (ret < 0) 845 - return ret; 846 - } 847 - 848 - /* Read and check the sensor version */ 849 - data = mt9t001_read(client, MT9T001_CHIP_VERSION); 850 - if (data != MT9T001_CHIP_ID) { 851 - dev_err(&client->dev, "MT9T001 not detected, wrong version " 852 - "0x%04x\n", data); 853 - return -ENODEV; 854 - } 855 - 856 - dev_info(&client->dev, "MT9T001 detected at address 0x%02x\n", 857 - client->addr); 858 - 859 - return ret; 860 - } 861 681 862 682 static int mt9t001_probe(struct i2c_client *client, 863 683 const struct i2c_device_id *did) ··· 838 740 return -EIO; 839 741 } 840 742 841 - ret = mt9t001_video_probe(client); 842 - if (ret < 0) 843 - return ret; 844 - 845 743 mt9t001 = devm_kzalloc(&client->dev, sizeof(*mt9t001), GFP_KERNEL); 846 744 if (!mt9t001) 847 745 return -ENOMEM; 746 + 747 + mutex_init(&mt9t001->power_lock); 748 + mt9t001->output_control = MT9T001_OUTPUT_CONTROL_DEF; 749 + 750 + mt9t001->regulators[0].supply = "vdd"; 751 + mt9t001->regulators[1].supply = "vaa"; 752 + 753 + ret = devm_regulator_bulk_get(&client->dev, 2, mt9t001->regulators); 754 + if (ret < 0) { 755 + dev_err(&client->dev, "Unable to get regulators\n"); 756 + return ret; 757 + } 848 758 849 759 v4l2_ctrl_handler_init(&mt9t001->ctrls, ARRAY_SIZE(mt9t001_ctrls) + 850 760 ARRAY_SIZE(mt9t001_gains) + 4);