diff options
| author | Jacopo Mondi <jacopo+renesas@jmondi.org> | 2018-03-12 09:43:03 -0400 |
|---|---|---|
| committer | Mauro Carvalho Chehab <mchehab@s-opensource.com> | 2018-03-21 15:29:07 -0400 |
| commit | 6a26f141bf6200a1b3537c24bd4a8d37f23fbe57 (patch) | |
| tree | ea939ecba156da6d2fdf4d3a0bcd5920e132eb01 | |
| parent | 7641b04421954ea092b8fa7edbf904c3852875b5 (diff) | |
media: i2c: mt9t112: Remove soc_camera dependencies
Remove soc_camera framework dependencies from mt9t112 sensor driver.
- Handle clk, gpios and power routines
- Register async subdev
- Remove deprecated g/s_mbus_config operations
- Remove driver flags
- Change driver interface and add kernel doc
- Adjust build system
- Fix code style issues reported by checkpatch in strict mode
This commit does not remove the original soc_camera based driver as long
as other platforms depends on soc_camera framework.
As I don't have access to a working camera module, this change has only
been compile tested.
Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
| -rw-r--r-- | drivers/media/i2c/Kconfig | 11 | ||||
| -rw-r--r-- | drivers/media/i2c/Makefile | 1 | ||||
| -rw-r--r-- | drivers/media/i2c/mt9t112.c | 403 | ||||
| -rw-r--r-- | drivers/media/i2c/soc_camera/mt9t112.c | 2 | ||||
| -rw-r--r-- | include/media/i2c/mt9t112.h | 17 |
5 files changed, 210 insertions, 224 deletions
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index d7bba0e3f30e..541f0d28afd8 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig | |||
| @@ -788,6 +788,17 @@ config VIDEO_MT9T001 | |||
| 788 | This is a Video4Linux2 sensor-level driver for the Aptina | 788 | This is a Video4Linux2 sensor-level driver for the Aptina |
| 789 | (Micron) mt0t001 3 Mpixel camera. | 789 | (Micron) mt0t001 3 Mpixel camera. |
| 790 | 790 | ||
| 791 | config VIDEO_MT9T112 | ||
| 792 | tristate "Aptina MT9T111/MT9T112 support" | ||
| 793 | depends on I2C && VIDEO_V4L2 | ||
| 794 | depends on MEDIA_CAMERA_SUPPORT | ||
| 795 | ---help--- | ||
| 796 | This is a Video4Linux2 sensor-level driver for the Aptina | ||
| 797 | (Micron) MT9T111 and MT9T112 3 Mpixel camera. | ||
| 798 | |||
| 799 | To compile this driver as a module, choose M here: the | ||
| 800 | module will be called mt9t112. | ||
| 801 | |||
| 791 | config VIDEO_MT9V011 | 802 | config VIDEO_MT9V011 |
| 792 | tristate "Micron mt9v011 sensor support" | 803 | tristate "Micron mt9v011 sensor support" |
| 793 | depends on I2C && VIDEO_V4L2 | 804 | depends on I2C && VIDEO_V4L2 |
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index cc30178e3347..ea34aee1a85a 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile | |||
| @@ -80,6 +80,7 @@ obj-$(CONFIG_VIDEO_MT9M032) += mt9m032.o | |||
| 80 | obj-$(CONFIG_VIDEO_MT9M111) += mt9m111.o | 80 | obj-$(CONFIG_VIDEO_MT9M111) += mt9m111.o |
| 81 | obj-$(CONFIG_VIDEO_MT9P031) += mt9p031.o | 81 | obj-$(CONFIG_VIDEO_MT9P031) += mt9p031.o |
| 82 | obj-$(CONFIG_VIDEO_MT9T001) += mt9t001.o | 82 | obj-$(CONFIG_VIDEO_MT9T001) += mt9t001.o |
| 83 | obj-$(CONFIG_VIDEO_MT9T112) += mt9t112.o | ||
| 83 | obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o | 84 | obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o |
| 84 | obj-$(CONFIG_VIDEO_MT9V032) += mt9v032.o | 85 | obj-$(CONFIG_VIDEO_MT9V032) += mt9v032.o |
| 85 | obj-$(CONFIG_VIDEO_SR030PC30) += sr030pc30.o | 86 | obj-$(CONFIG_VIDEO_SR030PC30) += sr030pc30.o |
diff --git a/drivers/media/i2c/mt9t112.c b/drivers/media/i2c/mt9t112.c index 297d22ebcb18..af8cca984215 100644 --- a/drivers/media/i2c/mt9t112.c +++ b/drivers/media/i2c/mt9t112.c | |||
| @@ -1,6 +1,9 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 1 | /* | 2 | /* |
| 2 | * mt9t112 Camera Driver | 3 | * mt9t112 Camera Driver |
| 3 | * | 4 | * |
| 5 | * Copyright (C) 2018 Jacopo Mondi <jacopo+renesas@jmondi.org> | ||
| 6 | * | ||
| 4 | * Copyright (C) 2009 Renesas Solutions Corp. | 7 | * Copyright (C) 2009 Renesas Solutions Corp. |
| 5 | * Kuninori Morimoto <morimoto.kuninori@renesas.com> | 8 | * Kuninori Morimoto <morimoto.kuninori@renesas.com> |
| 6 | * | 9 | * |
| @@ -12,12 +15,14 @@ | |||
| 12 | * Copyright (C) 2008 Magnus Damm | 15 | * Copyright (C) 2008 Magnus Damm |
| 13 | * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de> | 16 | * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de> |
| 14 | * | 17 | * |
| 15 | * This program is free software; you can redistribute it and/or modify | 18 | * TODO: This driver lacks support for frame rate control due to missing |
| 16 | * it under the terms of the GNU General Public License version 2 as | 19 | * register level documentation and suitable hardware for testing. |
| 17 | * published by the Free Software Foundation. | 20 | * v4l-utils compliance tools will report errors. |
| 18 | */ | 21 | */ |
| 19 | 22 | ||
| 23 | #include <linux/clk.h> | ||
| 20 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
| 25 | #include <linux/gpio/consumer.h> | ||
| 21 | #include <linux/i2c.h> | 26 | #include <linux/i2c.h> |
| 22 | #include <linux/init.h> | 27 | #include <linux/init.h> |
| 23 | #include <linux/module.h> | 28 | #include <linux/module.h> |
| @@ -26,17 +31,16 @@ | |||
| 26 | #include <linux/videodev2.h> | 31 | #include <linux/videodev2.h> |
| 27 | 32 | ||
| 28 | #include <media/i2c/mt9t112.h> | 33 | #include <media/i2c/mt9t112.h> |
| 29 | #include <media/soc_camera.h> | ||
| 30 | #include <media/v4l2-clk.h> | ||
| 31 | #include <media/v4l2-common.h> | 34 | #include <media/v4l2-common.h> |
| 32 | #include <media/v4l2-image-sizes.h> | 35 | #include <media/v4l2-image-sizes.h> |
| 36 | #include <media/v4l2-subdev.h> | ||
| 33 | 37 | ||
| 34 | /* you can check PLL/clock info */ | 38 | /* you can check PLL/clock info */ |
| 35 | /* #define EXT_CLOCK 24000000 */ | 39 | /* #define EXT_CLOCK 24000000 */ |
| 36 | 40 | ||
| 37 | /************************************************************************ | 41 | /************************************************************************ |
| 38 | macro | 42 | * macro |
| 39 | ************************************************************************/ | 43 | ***********************************************************************/ |
| 40 | /* | 44 | /* |
| 41 | * frame size | 45 | * frame size |
| 42 | */ | 46 | */ |
| @@ -74,8 +78,8 @@ | |||
| 74 | #define VAR8(id, offset) _VAR(id, offset, 0x8000) | 78 | #define VAR8(id, offset) _VAR(id, offset, 0x8000) |
| 75 | 79 | ||
| 76 | /************************************************************************ | 80 | /************************************************************************ |
| 77 | struct | 81 | * struct |
| 78 | ************************************************************************/ | 82 | ***********************************************************************/ |
| 79 | struct mt9t112_format { | 83 | struct mt9t112_format { |
| 80 | u32 code; | 84 | u32 code; |
| 81 | enum v4l2_colorspace colorspace; | 85 | enum v4l2_colorspace colorspace; |
| @@ -85,21 +89,19 @@ struct mt9t112_format { | |||
| 85 | 89 | ||
| 86 | struct mt9t112_priv { | 90 | struct mt9t112_priv { |
| 87 | struct v4l2_subdev subdev; | 91 | struct v4l2_subdev subdev; |
| 88 | struct mt9t112_camera_info *info; | 92 | struct mt9t112_platform_data *info; |
| 89 | struct i2c_client *client; | 93 | struct i2c_client *client; |
| 90 | struct v4l2_rect frame; | 94 | struct v4l2_rect frame; |
| 91 | struct v4l2_clk *clk; | 95 | struct clk *clk; |
| 96 | struct gpio_desc *standby_gpio; | ||
| 92 | const struct mt9t112_format *format; | 97 | const struct mt9t112_format *format; |
| 93 | int num_formats; | 98 | int num_formats; |
| 94 | u32 flags; | 99 | bool init_done; |
| 95 | /* for flags */ | ||
| 96 | #define INIT_DONE (1 << 0) | ||
| 97 | #define PCLK_RISING (1 << 1) | ||
| 98 | }; | 100 | }; |
| 99 | 101 | ||
| 100 | /************************************************************************ | 102 | /************************************************************************ |
| 101 | supported format | 103 | * supported format |
| 102 | ************************************************************************/ | 104 | ***********************************************************************/ |
| 103 | 105 | ||
| 104 | static const struct mt9t112_format mt9t112_cfmts[] = { | 106 | static const struct mt9t112_format mt9t112_cfmts[] = { |
| 105 | { | 107 | { |
| @@ -136,8 +138,8 @@ static const struct mt9t112_format mt9t112_cfmts[] = { | |||
| 136 | }; | 138 | }; |
| 137 | 139 | ||
| 138 | /************************************************************************ | 140 | /************************************************************************ |
| 139 | general function | 141 | * general function |
| 140 | ************************************************************************/ | 142 | ***********************************************************************/ |
| 141 | static struct mt9t112_priv *to_mt9t112(const struct i2c_client *client) | 143 | static struct mt9t112_priv *to_mt9t112(const struct i2c_client *client) |
| 142 | { | 144 | { |
| 143 | return container_of(i2c_get_clientdata(client), | 145 | return container_of(i2c_get_clientdata(client), |
| @@ -164,15 +166,15 @@ static int __mt9t112_reg_read(const struct i2c_client *client, u16 command) | |||
| 164 | msg[1].buf = buf; | 166 | msg[1].buf = buf; |
| 165 | 167 | ||
| 166 | /* | 168 | /* |
| 167 | * if return value of this function is < 0, | 169 | * If return value of this function is < 0, it means error, else, |
| 168 | * it mean error. | 170 | * below 16bit is valid data. |
| 169 | * else, under 16bit is valid data. | ||
| 170 | */ | 171 | */ |
| 171 | ret = i2c_transfer(client->adapter, msg, 2); | 172 | ret = i2c_transfer(client->adapter, msg, 2); |
| 172 | if (ret < 0) | 173 | if (ret < 0) |
| 173 | return ret; | 174 | return ret; |
| 174 | 175 | ||
| 175 | memcpy(&ret, buf, 2); | 176 | memcpy(&ret, buf, 2); |
| 177 | |||
| 176 | return swab16(ret); | 178 | return swab16(ret); |
| 177 | } | 179 | } |
| 178 | 180 | ||
| @@ -195,22 +197,19 @@ static int __mt9t112_reg_write(const struct i2c_client *client, | |||
| 195 | msg.buf = buf; | 197 | msg.buf = buf; |
| 196 | 198 | ||
| 197 | /* | 199 | /* |
| 198 | * i2c_transfer return message length, | 200 | * i2c_transfer return message length, but this function should |
| 199 | * but this function should return 0 if correct case | 201 | * return 0 if correct case. |
| 200 | */ | 202 | */ |
| 201 | ret = i2c_transfer(client->adapter, &msg, 1); | 203 | ret = i2c_transfer(client->adapter, &msg, 1); |
| 202 | if (ret >= 0) | ||
| 203 | ret = 0; | ||
| 204 | 204 | ||
| 205 | return ret; | 205 | return ret >= 0 ? 0 : ret; |
| 206 | } | 206 | } |
| 207 | 207 | ||
| 208 | static int __mt9t112_reg_mask_set(const struct i2c_client *client, | 208 | static int __mt9t112_reg_mask_set(const struct i2c_client *client, |
| 209 | u16 command, | 209 | u16 command, u16 mask, u16 set) |
| 210 | u16 mask, | ||
| 211 | u16 set) | ||
| 212 | { | 210 | { |
| 213 | int val = __mt9t112_reg_read(client, command); | 211 | int val = __mt9t112_reg_read(client, command); |
| 212 | |||
| 214 | if (val < 0) | 213 | if (val < 0) |
| 215 | return val; | 214 | return val; |
| 216 | 215 | ||
| @@ -245,11 +244,10 @@ static int __mt9t112_mcu_write(const struct i2c_client *client, | |||
| 245 | } | 244 | } |
| 246 | 245 | ||
| 247 | static int __mt9t112_mcu_mask_set(const struct i2c_client *client, | 246 | static int __mt9t112_mcu_mask_set(const struct i2c_client *client, |
| 248 | u16 command, | 247 | u16 command, u16 mask, u16 set) |
| 249 | u16 mask, | ||
| 250 | u16 set) | ||
| 251 | { | 248 | { |
| 252 | int val = __mt9t112_mcu_read(client, command); | 249 | int val = __mt9t112_mcu_read(client, command); |
| 250 | |||
| 253 | if (val < 0) | 251 | if (val < 0) |
| 254 | return val; | 252 | return val; |
| 255 | 253 | ||
| @@ -264,7 +262,7 @@ static int mt9t112_reset(const struct i2c_client *client) | |||
| 264 | int ret; | 262 | int ret; |
| 265 | 263 | ||
| 266 | mt9t112_reg_mask_set(ret, client, 0x001a, 0x0001, 0x0001); | 264 | mt9t112_reg_mask_set(ret, client, 0x001a, 0x0001, 0x0001); |
| 267 | msleep(1); | 265 | usleep_range(1000, 5000); |
| 268 | mt9t112_reg_mask_set(ret, client, 0x001a, 0x0001, 0x0000); | 266 | mt9t112_reg_mask_set(ret, client, 0x001a, 0x0001, 0x0000); |
| 269 | 267 | ||
| 270 | return ret; | 268 | return ret; |
| @@ -303,71 +301,64 @@ static int mt9t112_clock_info(const struct i2c_client *client, u32 ext) | |||
| 303 | m = n & 0x00ff; | 301 | m = n & 0x00ff; |
| 304 | n = (n >> 8) & 0x003f; | 302 | n = (n >> 8) & 0x003f; |
| 305 | 303 | ||
| 306 | enable = ((6000 > ext) || (54000 < ext)) ? "X" : ""; | 304 | enable = ((ext < 6000) || (ext > 54000)) ? "X" : ""; |
| 307 | dev_dbg(&client->dev, "EXTCLK : %10u K %s\n", ext, enable); | 305 | dev_dbg(&client->dev, "EXTCLK : %10u K %s\n", ext, enable); |
| 308 | 306 | ||
| 309 | vco = 2 * m * ext / (n+1); | 307 | vco = 2 * m * ext / (n + 1); |
| 310 | enable = ((384000 > vco) || (768000 < vco)) ? "X" : ""; | 308 | enable = ((vco < 384000) || (vco > 768000)) ? "X" : ""; |
| 311 | dev_dbg(&client->dev, "VCO : %10u K %s\n", vco, enable); | 309 | dev_dbg(&client->dev, "VCO : %10u K %s\n", vco, enable); |
| 312 | 310 | ||
| 313 | clk = vco / (p1+1) / (p2+1); | 311 | clk = vco / (p1 + 1) / (p2 + 1); |
| 314 | enable = (96000 < clk) ? "X" : ""; | 312 | enable = (clk > 96000) ? "X" : ""; |
| 315 | dev_dbg(&client->dev, "PIXCLK : %10u K %s\n", clk, enable); | 313 | dev_dbg(&client->dev, "PIXCLK : %10u K %s\n", clk, enable); |
| 316 | 314 | ||
| 317 | clk = vco / (p3+1); | 315 | clk = vco / (p3 + 1); |
| 318 | enable = (768000 < clk) ? "X" : ""; | 316 | enable = (clk > 768000) ? "X" : ""; |
| 319 | dev_dbg(&client->dev, "MIPICLK : %10u K %s\n", clk, enable); | 317 | dev_dbg(&client->dev, "MIPICLK : %10u K %s\n", clk, enable); |
| 320 | 318 | ||
| 321 | clk = vco / (p6+1); | 319 | clk = vco / (p6 + 1); |
| 322 | enable = (96000 < clk) ? "X" : ""; | 320 | enable = (clk > 96000) ? "X" : ""; |
| 323 | dev_dbg(&client->dev, "MCU CLK : %10u K %s\n", clk, enable); | 321 | dev_dbg(&client->dev, "MCU CLK : %10u K %s\n", clk, enable); |
| 324 | 322 | ||
| 325 | clk = vco / (p5+1); | 323 | clk = vco / (p5 + 1); |
| 326 | enable = (54000 < clk) ? "X" : ""; | 324 | enable = (clk > 54000) ? "X" : ""; |
| 327 | dev_dbg(&client->dev, "SOC CLK : %10u K %s\n", clk, enable); | 325 | dev_dbg(&client->dev, "SOC CLK : %10u K %s\n", clk, enable); |
| 328 | 326 | ||
| 329 | clk = vco / (p4+1); | 327 | clk = vco / (p4 + 1); |
| 330 | enable = (70000 < clk) ? "X" : ""; | 328 | enable = (clk > 70000) ? "X" : ""; |
| 331 | dev_dbg(&client->dev, "Sensor CLK : %10u K %s\n", clk, enable); | 329 | dev_dbg(&client->dev, "Sensor CLK : %10u K %s\n", clk, enable); |
| 332 | 330 | ||
| 333 | clk = vco / (p7+1); | 331 | clk = vco / (p7 + 1); |
| 334 | dev_dbg(&client->dev, "External sensor : %10u K\n", clk); | 332 | dev_dbg(&client->dev, "External sensor : %10u K\n", clk); |
| 335 | 333 | ||
| 336 | clk = ext / (n+1); | 334 | clk = ext / (n + 1); |
| 337 | enable = ((2000 > clk) || (24000 < clk)) ? "X" : ""; | 335 | enable = ((clk < 2000) || (clk > 24000)) ? "X" : ""; |
| 338 | dev_dbg(&client->dev, "PFD : %10u K %s\n", clk, enable); | 336 | dev_dbg(&client->dev, "PFD : %10u K %s\n", clk, enable); |
| 339 | 337 | ||
| 340 | return 0; | 338 | return 0; |
| 341 | } | 339 | } |
| 342 | #endif | 340 | #endif |
| 343 | 341 | ||
| 344 | static void mt9t112_frame_check(u32 *width, u32 *height, u32 *left, u32 *top) | ||
| 345 | { | ||
| 346 | soc_camera_limit_side(left, width, 0, 0, MAX_WIDTH); | ||
| 347 | soc_camera_limit_side(top, height, 0, 0, MAX_HEIGHT); | ||
| 348 | } | ||
| 349 | |||
| 350 | static int mt9t112_set_a_frame_size(const struct i2c_client *client, | 342 | static int mt9t112_set_a_frame_size(const struct i2c_client *client, |
| 351 | u16 width, | 343 | u16 width, u16 height) |
| 352 | u16 height) | ||
| 353 | { | 344 | { |
| 354 | int ret; | 345 | int ret; |
| 355 | u16 wstart = (MAX_WIDTH - width) / 2; | 346 | u16 wstart = (MAX_WIDTH - width) / 2; |
| 356 | u16 hstart = (MAX_HEIGHT - height) / 2; | 347 | u16 hstart = (MAX_HEIGHT - height) / 2; |
| 357 | 348 | ||
| 358 | /* (Context A) Image Width/Height */ | 349 | /* (Context A) Image Width/Height. */ |
| 359 | mt9t112_mcu_write(ret, client, VAR(26, 0), width); | 350 | mt9t112_mcu_write(ret, client, VAR(26, 0), width); |
| 360 | mt9t112_mcu_write(ret, client, VAR(26, 2), height); | 351 | mt9t112_mcu_write(ret, client, VAR(26, 2), height); |
| 361 | 352 | ||
| 362 | /* (Context A) Output Width/Height */ | 353 | /* (Context A) Output Width/Height. */ |
| 363 | mt9t112_mcu_write(ret, client, VAR(18, 43), 8 + width); | 354 | mt9t112_mcu_write(ret, client, VAR(18, 43), 8 + width); |
| 364 | mt9t112_mcu_write(ret, client, VAR(18, 45), 8 + height); | 355 | mt9t112_mcu_write(ret, client, VAR(18, 45), 8 + height); |
| 365 | 356 | ||
| 366 | /* (Context A) Start Row/Column */ | 357 | /* (Context A) Start Row/Column. */ |
| 367 | mt9t112_mcu_write(ret, client, VAR(18, 2), 4 + hstart); | 358 | mt9t112_mcu_write(ret, client, VAR(18, 2), 4 + hstart); |
| 368 | mt9t112_mcu_write(ret, client, VAR(18, 4), 4 + wstart); | 359 | mt9t112_mcu_write(ret, client, VAR(18, 4), 4 + wstart); |
| 369 | 360 | ||
| 370 | /* (Context A) End Row/Column */ | 361 | /* (Context A) End Row/Column. */ |
| 371 | mt9t112_mcu_write(ret, client, VAR(18, 6), 11 + height + hstart); | 362 | mt9t112_mcu_write(ret, client, VAR(18, 6), 11 + height + hstart); |
| 372 | mt9t112_mcu_write(ret, client, VAR(18, 8), 11 + width + wstart); | 363 | mt9t112_mcu_write(ret, client, VAR(18, 8), 11 + width + wstart); |
| 373 | 364 | ||
| @@ -377,35 +368,27 @@ static int mt9t112_set_a_frame_size(const struct i2c_client *client, | |||
| 377 | } | 368 | } |
| 378 | 369 | ||
| 379 | static int mt9t112_set_pll_dividers(const struct i2c_client *client, | 370 | static int mt9t112_set_pll_dividers(const struct i2c_client *client, |
| 380 | u8 m, u8 n, | 371 | u8 m, u8 n, u8 p1, u8 p2, u8 p3, u8 p4, |
| 381 | u8 p1, u8 p2, u8 p3, | 372 | u8 p5, u8 p6, u8 p7) |
| 382 | u8 p4, u8 p5, u8 p6, | ||
| 383 | u8 p7) | ||
| 384 | { | 373 | { |
| 385 | int ret; | 374 | int ret; |
| 386 | u16 val; | 375 | u16 val; |
| 387 | 376 | ||
| 388 | /* N/M */ | 377 | /* N/M */ |
| 389 | val = (n << 8) | | 378 | val = (n << 8) | (m << 0); |
| 390 | (m << 0); | ||
| 391 | mt9t112_reg_mask_set(ret, client, 0x0010, 0x3fff, val); | 379 | mt9t112_reg_mask_set(ret, client, 0x0010, 0x3fff, val); |
| 392 | 380 | ||
| 393 | /* P1/P2/P3 */ | 381 | /* P1/P2/P3 */ |
| 394 | val = ((p3 & 0x0F) << 8) | | 382 | val = ((p3 & 0x0F) << 8) | ((p2 & 0x0F) << 4) | ((p1 & 0x0F) << 0); |
| 395 | ((p2 & 0x0F) << 4) | | ||
| 396 | ((p1 & 0x0F) << 0); | ||
| 397 | mt9t112_reg_mask_set(ret, client, 0x0012, 0x0fff, val); | 383 | mt9t112_reg_mask_set(ret, client, 0x0012, 0x0fff, val); |
| 398 | 384 | ||
| 399 | /* P4/P5/P6 */ | 385 | /* P4/P5/P6 */ |
| 400 | val = (0x7 << 12) | | 386 | val = (0x7 << 12) | ((p6 & 0x0F) << 8) | ((p5 & 0x0F) << 4) | |
| 401 | ((p6 & 0x0F) << 8) | | ||
| 402 | ((p5 & 0x0F) << 4) | | ||
| 403 | ((p4 & 0x0F) << 0); | 387 | ((p4 & 0x0F) << 0); |
| 404 | mt9t112_reg_mask_set(ret, client, 0x002A, 0x7fff, val); | 388 | mt9t112_reg_mask_set(ret, client, 0x002A, 0x7fff, val); |
| 405 | 389 | ||
| 406 | /* P7 */ | 390 | /* P7 */ |
| 407 | val = (0x1 << 12) | | 391 | val = (0x1 << 12) | ((p7 & 0x0F) << 0); |
| 408 | ((p7 & 0x0F) << 0); | ||
| 409 | mt9t112_reg_mask_set(ret, client, 0x002C, 0x100f, val); | 392 | mt9t112_reg_mask_set(ret, client, 0x002C, 0x100f, val); |
| 410 | 393 | ||
| 411 | return ret; | 394 | return ret; |
| @@ -418,19 +401,15 @@ static int mt9t112_init_pll(const struct i2c_client *client) | |||
| 418 | 401 | ||
| 419 | mt9t112_reg_mask_set(ret, client, 0x0014, 0x003, 0x0001); | 402 | mt9t112_reg_mask_set(ret, client, 0x0014, 0x003, 0x0001); |
| 420 | 403 | ||
| 421 | /* PLL control: BYPASS PLL = 8517 */ | 404 | /* PLL control: BYPASS PLL = 8517. */ |
| 422 | mt9t112_reg_write(ret, client, 0x0014, 0x2145); | 405 | mt9t112_reg_write(ret, client, 0x0014, 0x2145); |
| 423 | 406 | ||
| 424 | /* Replace these registers when new timing parameters are generated */ | 407 | /* Replace these registers when new timing parameters are generated. */ |
| 425 | mt9t112_set_pll_dividers(client, | 408 | mt9t112_set_pll_dividers(client, |
| 426 | priv->info->divider.m, | 409 | priv->info->divider.m, priv->info->divider.n, |
| 427 | priv->info->divider.n, | 410 | priv->info->divider.p1, priv->info->divider.p2, |
| 428 | priv->info->divider.p1, | 411 | priv->info->divider.p3, priv->info->divider.p4, |
| 429 | priv->info->divider.p2, | 412 | priv->info->divider.p5, priv->info->divider.p6, |
| 430 | priv->info->divider.p3, | ||
| 431 | priv->info->divider.p4, | ||
| 432 | priv->info->divider.p5, | ||
| 433 | priv->info->divider.p6, | ||
| 434 | priv->info->divider.p7); | 413 | priv->info->divider.p7); |
| 435 | 414 | ||
| 436 | /* | 415 | /* |
| @@ -452,20 +431,21 @@ static int mt9t112_init_pll(const struct i2c_client *client) | |||
| 452 | * I2C Master Clock Divider | 431 | * I2C Master Clock Divider |
| 453 | */ | 432 | */ |
| 454 | mt9t112_reg_write(ret, client, 0x0014, 0x3046); | 433 | mt9t112_reg_write(ret, client, 0x0014, 0x3046); |
| 455 | mt9t112_reg_write(ret, client, 0x0016, 0x0400); /* JPEG initialization workaround */ | 434 | /* JPEG initialization workaround */ |
| 435 | mt9t112_reg_write(ret, client, 0x0016, 0x0400); | ||
| 456 | mt9t112_reg_write(ret, client, 0x0022, 0x0190); | 436 | mt9t112_reg_write(ret, client, 0x0022, 0x0190); |
| 457 | mt9t112_reg_write(ret, client, 0x3B84, 0x0212); | 437 | mt9t112_reg_write(ret, client, 0x3B84, 0x0212); |
| 458 | 438 | ||
| 459 | /* External sensor clock is PLL bypass */ | 439 | /* External sensor clock is PLL bypass. */ |
| 460 | mt9t112_reg_write(ret, client, 0x002E, 0x0500); | 440 | mt9t112_reg_write(ret, client, 0x002E, 0x0500); |
| 461 | 441 | ||
| 462 | mt9t112_reg_mask_set(ret, client, 0x0018, 0x0002, 0x0002); | 442 | mt9t112_reg_mask_set(ret, client, 0x0018, 0x0002, 0x0002); |
| 463 | mt9t112_reg_mask_set(ret, client, 0x3B82, 0x0004, 0x0004); | 443 | mt9t112_reg_mask_set(ret, client, 0x3B82, 0x0004, 0x0004); |
| 464 | 444 | ||
| 465 | /* MCU disabled */ | 445 | /* MCU disabled. */ |
| 466 | mt9t112_reg_mask_set(ret, client, 0x0018, 0x0004, 0x0004); | 446 | mt9t112_reg_mask_set(ret, client, 0x0018, 0x0004, 0x0004); |
| 467 | 447 | ||
| 468 | /* out of standby */ | 448 | /* Out of standby. */ |
| 469 | mt9t112_reg_mask_set(ret, client, 0x0018, 0x0001, 0); | 449 | mt9t112_reg_mask_set(ret, client, 0x0018, 0x0001, 0); |
| 470 | 450 | ||
| 471 | mdelay(50); | 451 | mdelay(50); |
| @@ -487,10 +467,10 @@ static int mt9t112_init_pll(const struct i2c_client *client) | |||
| 487 | mt9t112_reg_write(ret, client, 0x0614, 0x0001); | 467 | mt9t112_reg_write(ret, client, 0x0614, 0x0001); |
| 488 | mdelay(1); | 468 | mdelay(1); |
| 489 | 469 | ||
| 490 | /* poll to verify out of standby. Must Poll this bit */ | 470 | /* Poll to verify out of standby. Must Poll this bit. */ |
| 491 | for (i = 0; i < 100; i++) { | 471 | for (i = 0; i < 100; i++) { |
| 492 | mt9t112_reg_read(data, client, 0x0018); | 472 | mt9t112_reg_read(data, client, 0x0018); |
| 493 | if (!(0x4000 & data)) | 473 | if (!(data & 0x4000)) |
| 494 | break; | 474 | break; |
| 495 | 475 | ||
| 496 | mdelay(10); | 476 | mdelay(10); |
| @@ -501,7 +481,6 @@ static int mt9t112_init_pll(const struct i2c_client *client) | |||
| 501 | 481 | ||
| 502 | static int mt9t112_init_setting(const struct i2c_client *client) | 482 | static int mt9t112_init_setting(const struct i2c_client *client) |
| 503 | { | 483 | { |
| 504 | |||
| 505 | int ret; | 484 | int ret; |
| 506 | 485 | ||
| 507 | /* Adaptive Output Clock (A) */ | 486 | /* Adaptive Output Clock (A) */ |
| @@ -562,11 +541,11 @@ static int mt9t112_init_setting(const struct i2c_client *client) | |||
| 562 | mt9t112_mcu_write(ret, client, VAR(18, 109), 0x0AF0); | 541 | mt9t112_mcu_write(ret, client, VAR(18, 109), 0x0AF0); |
| 563 | 542 | ||
| 564 | /* | 543 | /* |
| 565 | * Flicker Dectection registers | 544 | * Flicker Dectection registers. |
| 566 | * This section should be replaced whenever new Timing file is generated | 545 | * This section should be replaced whenever new timing file is |
| 567 | * All the following registers need to be replaced | 546 | * generated. All the following registers need to be replaced. |
| 568 | * Following registers are generated from Register Wizard but user can | 547 | * Following registers are generated from Register Wizard but user can |
| 569 | * modify them. For detail see auto flicker detection tuning | 548 | * modify them. For detail see auto flicker detection tuning. |
| 570 | */ | 549 | */ |
| 571 | 550 | ||
| 572 | /* FD_FDPERIOD_SELECT */ | 551 | /* FD_FDPERIOD_SELECT */ |
| @@ -579,47 +558,47 @@ static int mt9t112_init_setting(const struct i2c_client *client) | |||
| 579 | mt9t112_mcu_write(ret, client, VAR(26, 17), 0x0003); | 558 | mt9t112_mcu_write(ret, client, VAR(26, 17), 0x0003); |
| 580 | 559 | ||
| 581 | /* | 560 | /* |
| 582 | * AFD range detection tuning registers | 561 | * AFD range detection tuning registers. |
| 583 | */ | 562 | */ |
| 584 | 563 | ||
| 585 | /* search_f1_50 */ | 564 | /* Search_f1_50 */ |
| 586 | mt9t112_mcu_write(ret, client, VAR8(18, 165), 0x25); | 565 | mt9t112_mcu_write(ret, client, VAR8(18, 165), 0x25); |
| 587 | 566 | ||
| 588 | /* search_f2_50 */ | 567 | /* Search_f2_50 */ |
| 589 | mt9t112_mcu_write(ret, client, VAR8(18, 166), 0x28); | 568 | mt9t112_mcu_write(ret, client, VAR8(18, 166), 0x28); |
| 590 | 569 | ||
| 591 | /* search_f1_60 */ | 570 | /* Search_f1_60 */ |
| 592 | mt9t112_mcu_write(ret, client, VAR8(18, 167), 0x2C); | 571 | mt9t112_mcu_write(ret, client, VAR8(18, 167), 0x2C); |
| 593 | 572 | ||
| 594 | /* search_f2_60 */ | 573 | /* Search_f2_60 */ |
| 595 | mt9t112_mcu_write(ret, client, VAR8(18, 168), 0x2F); | 574 | mt9t112_mcu_write(ret, client, VAR8(18, 168), 0x2F); |
| 596 | 575 | ||
| 597 | /* period_50Hz (A) */ | 576 | /* Period_50Hz (A) */ |
| 598 | mt9t112_mcu_write(ret, client, VAR8(18, 68), 0xBA); | 577 | mt9t112_mcu_write(ret, client, VAR8(18, 68), 0xBA); |
| 599 | 578 | ||
| 600 | /* secret register by aptina */ | 579 | /* Secret register by Aptina. */ |
| 601 | /* period_50Hz (A MSB) */ | 580 | /* Period_50Hz (A MSB) */ |
| 602 | mt9t112_mcu_write(ret, client, VAR8(18, 303), 0x00); | 581 | mt9t112_mcu_write(ret, client, VAR8(18, 303), 0x00); |
| 603 | 582 | ||
| 604 | /* period_60Hz (A) */ | 583 | /* Period_60Hz (A) */ |
| 605 | mt9t112_mcu_write(ret, client, VAR8(18, 69), 0x9B); | 584 | mt9t112_mcu_write(ret, client, VAR8(18, 69), 0x9B); |
| 606 | 585 | ||
| 607 | /* secret register by aptina */ | 586 | /* Secret register by Aptina. */ |
| 608 | /* period_60Hz (A MSB) */ | 587 | /* Period_60Hz (A MSB) */ |
| 609 | mt9t112_mcu_write(ret, client, VAR8(18, 301), 0x00); | 588 | mt9t112_mcu_write(ret, client, VAR8(18, 301), 0x00); |
| 610 | 589 | ||
| 611 | /* period_50Hz (B) */ | 590 | /* Period_50Hz (B) */ |
| 612 | mt9t112_mcu_write(ret, client, VAR8(18, 140), 0x82); | 591 | mt9t112_mcu_write(ret, client, VAR8(18, 140), 0x82); |
| 613 | 592 | ||
| 614 | /* secret register by aptina */ | 593 | /* Secret register by Aptina. */ |
| 615 | /* period_50Hz (B) MSB */ | 594 | /* Period_50Hz (B) MSB */ |
| 616 | mt9t112_mcu_write(ret, client, VAR8(18, 304), 0x00); | 595 | mt9t112_mcu_write(ret, client, VAR8(18, 304), 0x00); |
| 617 | 596 | ||
| 618 | /* period_60Hz (B) */ | 597 | /* Period_60Hz (B) */ |
| 619 | mt9t112_mcu_write(ret, client, VAR8(18, 141), 0x6D); | 598 | mt9t112_mcu_write(ret, client, VAR8(18, 141), 0x6D); |
| 620 | 599 | ||
| 621 | /* secret register by aptina */ | 600 | /* Secret register by Aptina. */ |
| 622 | /* period_60Hz (B) MSB */ | 601 | /* Period_60Hz (B) MSB */ |
| 623 | mt9t112_mcu_write(ret, client, VAR8(18, 302), 0x00); | 602 | mt9t112_mcu_write(ret, client, VAR8(18, 302), 0x00); |
| 624 | 603 | ||
| 625 | /* FD Mode */ | 604 | /* FD Mode */ |
| @@ -693,49 +672,50 @@ static int mt9t112_init_camera(const struct i2c_client *client) | |||
| 693 | int ret; | 672 | int ret; |
| 694 | 673 | ||
| 695 | ECHECKER(ret, mt9t112_reset(client)); | 674 | ECHECKER(ret, mt9t112_reset(client)); |
| 696 | |||
| 697 | ECHECKER(ret, mt9t112_init_pll(client)); | 675 | ECHECKER(ret, mt9t112_init_pll(client)); |
| 698 | |||
| 699 | ECHECKER(ret, mt9t112_init_setting(client)); | 676 | ECHECKER(ret, mt9t112_init_setting(client)); |
| 700 | |||
| 701 | ECHECKER(ret, mt9t112_auto_focus_setting(client)); | 677 | ECHECKER(ret, mt9t112_auto_focus_setting(client)); |
| 702 | 678 | ||
| 703 | mt9t112_reg_mask_set(ret, client, 0x0018, 0x0004, 0); | 679 | mt9t112_reg_mask_set(ret, client, 0x0018, 0x0004, 0); |
| 704 | 680 | ||
| 705 | /* Analog setting B */ | 681 | /* Analog setting B.*/ |
| 706 | mt9t112_reg_write(ret, client, 0x3084, 0x2409); | 682 | mt9t112_reg_write(ret, client, 0x3084, 0x2409); |
| 707 | mt9t112_reg_write(ret, client, 0x3092, 0x0A49); | 683 | mt9t112_reg_write(ret, client, 0x3092, 0x0A49); |
| 708 | mt9t112_reg_write(ret, client, 0x3094, 0x4949); | 684 | mt9t112_reg_write(ret, client, 0x3094, 0x4949); |
| 709 | mt9t112_reg_write(ret, client, 0x3096, 0x4950); | 685 | mt9t112_reg_write(ret, client, 0x3096, 0x4950); |
| 710 | 686 | ||
| 711 | /* | 687 | /* |
| 712 | * Disable adaptive clock | 688 | * Disable adaptive clock. |
| 713 | * PRI_A_CONFIG_JPEG_OB_TX_CONTROL_VAR | 689 | * PRI_A_CONFIG_JPEG_OB_TX_CONTROL_VAR |
| 714 | * PRI_B_CONFIG_JPEG_OB_TX_CONTROL_VAR | 690 | * PRI_B_CONFIG_JPEG_OB_TX_CONTROL_VAR |
| 715 | */ | 691 | */ |
| 716 | mt9t112_mcu_write(ret, client, VAR(26, 160), 0x0A2E); | 692 | mt9t112_mcu_write(ret, client, VAR(26, 160), 0x0A2E); |
| 717 | mt9t112_mcu_write(ret, client, VAR(27, 160), 0x0A2E); | 693 | mt9t112_mcu_write(ret, client, VAR(27, 160), 0x0A2E); |
| 718 | 694 | ||
| 719 | /* Configure STatus in Status_before_length Format and enable header */ | 695 | /* |
| 720 | /* PRI_B_CONFIG_JPEG_OB_TX_CONTROL_VAR */ | 696 | * Configure Status in Status_before_length Format and enable header. |
| 697 | * PRI_B_CONFIG_JPEG_OB_TX_CONTROL_VAR | ||
| 698 | */ | ||
| 721 | mt9t112_mcu_write(ret, client, VAR(27, 144), 0x0CB4); | 699 | mt9t112_mcu_write(ret, client, VAR(27, 144), 0x0CB4); |
| 722 | 700 | ||
| 723 | /* Enable JPEG in context B */ | 701 | /* |
| 724 | /* PRI_B_CONFIG_JPEG_OB_TX_CONTROL_VAR */ | 702 | * Enable JPEG in context B. |
| 703 | * PRI_B_CONFIG_JPEG_OB_TX_CONTROL_VAR | ||
| 704 | */ | ||
| 725 | mt9t112_mcu_write(ret, client, VAR8(27, 142), 0x01); | 705 | mt9t112_mcu_write(ret, client, VAR8(27, 142), 0x01); |
| 726 | 706 | ||
| 727 | /* Disable Dac_TXLO */ | 707 | /* Disable Dac_TXLO. */ |
| 728 | mt9t112_reg_write(ret, client, 0x316C, 0x350F); | 708 | mt9t112_reg_write(ret, client, 0x316C, 0x350F); |
| 729 | 709 | ||
| 730 | /* Set max slew rates */ | 710 | /* Set max slew rates. */ |
| 731 | mt9t112_reg_write(ret, client, 0x1E, 0x777); | 711 | mt9t112_reg_write(ret, client, 0x1E, 0x777); |
| 732 | 712 | ||
| 733 | return ret; | 713 | return ret; |
| 734 | } | 714 | } |
| 735 | 715 | ||
| 736 | /************************************************************************ | 716 | /************************************************************************ |
| 737 | v4l2_subdev_core_ops | 717 | * v4l2_subdev_core_ops |
| 738 | ************************************************************************/ | 718 | ***********************************************************************/ |
| 739 | 719 | ||
| 740 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 720 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
| 741 | static int mt9t112_g_register(struct v4l2_subdev *sd, | 721 | static int mt9t112_g_register(struct v4l2_subdev *sd, |
| @@ -764,13 +744,40 @@ static int mt9t112_s_register(struct v4l2_subdev *sd, | |||
| 764 | } | 744 | } |
| 765 | #endif | 745 | #endif |
| 766 | 746 | ||
| 747 | static int mt9t112_power_on(struct mt9t112_priv *priv) | ||
| 748 | { | ||
| 749 | int ret; | ||
| 750 | |||
| 751 | ret = clk_prepare_enable(priv->clk); | ||
| 752 | if (ret) | ||
| 753 | return ret; | ||
| 754 | |||
| 755 | if (priv->standby_gpio) { | ||
| 756 | gpiod_set_value(priv->standby_gpio, 0); | ||
| 757 | msleep(100); | ||
| 758 | } | ||
| 759 | |||
| 760 | return 0; | ||
| 761 | } | ||
| 762 | |||
| 763 | static int mt9t112_power_off(struct mt9t112_priv *priv) | ||
| 764 | { | ||
| 765 | clk_disable_unprepare(priv->clk); | ||
| 766 | if (priv->standby_gpio) { | ||
| 767 | gpiod_set_value(priv->standby_gpio, 1); | ||
| 768 | msleep(100); | ||
| 769 | } | ||
| 770 | |||
| 771 | return 0; | ||
| 772 | } | ||
| 773 | |||
| 767 | static int mt9t112_s_power(struct v4l2_subdev *sd, int on) | 774 | static int mt9t112_s_power(struct v4l2_subdev *sd, int on) |
| 768 | { | 775 | { |
| 769 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 776 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| 770 | struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); | ||
| 771 | struct mt9t112_priv *priv = to_mt9t112(client); | 777 | struct mt9t112_priv *priv = to_mt9t112(client); |
| 772 | 778 | ||
| 773 | return soc_camera_set_power(&client->dev, ssdd, priv->clk, on); | 779 | return on ? mt9t112_power_on(priv) : |
| 780 | mt9t112_power_off(priv); | ||
| 774 | } | 781 | } |
| 775 | 782 | ||
| 776 | static const struct v4l2_subdev_core_ops mt9t112_subdev_core_ops = { | 783 | static const struct v4l2_subdev_core_ops mt9t112_subdev_core_ops = { |
| @@ -781,10 +788,9 @@ static const struct v4l2_subdev_core_ops mt9t112_subdev_core_ops = { | |||
| 781 | .s_power = mt9t112_s_power, | 788 | .s_power = mt9t112_s_power, |
| 782 | }; | 789 | }; |
| 783 | 790 | ||
| 784 | |||
| 785 | /************************************************************************ | 791 | /************************************************************************ |
| 786 | v4l2_subdev_video_ops | 792 | * v4l2_subdev_video_ops |
| 787 | ************************************************************************/ | 793 | **********************************************************************/ |
| 788 | static int mt9t112_s_stream(struct v4l2_subdev *sd, int enable) | 794 | static int mt9t112_s_stream(struct v4l2_subdev *sd, int enable) |
| 789 | { | 795 | { |
| 790 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 796 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| @@ -794,8 +800,7 @@ static int mt9t112_s_stream(struct v4l2_subdev *sd, int enable) | |||
| 794 | if (!enable) { | 800 | if (!enable) { |
| 795 | /* FIXME | 801 | /* FIXME |
| 796 | * | 802 | * |
| 797 | * If user selected large output size, | 803 | * If user selected large output size, and used it long time, |
| 798 | * and used it long time, | ||
| 799 | * mt9t112 camera will be very warm. | 804 | * mt9t112 camera will be very warm. |
| 800 | * | 805 | * |
| 801 | * But current driver can not stop mt9t112 camera. | 806 | * But current driver can not stop mt9t112 camera. |
| @@ -805,26 +810,25 @@ static int mt9t112_s_stream(struct v4l2_subdev *sd, int enable) | |||
| 805 | return ret; | 810 | return ret; |
| 806 | } | 811 | } |
| 807 | 812 | ||
| 808 | if (!(priv->flags & INIT_DONE)) { | 813 | if (!priv->init_done) { |
| 809 | u16 param = PCLK_RISING & priv->flags ? 0x0001 : 0x0000; | 814 | u16 param = MT9T112_FLAG_PCLK_RISING_EDGE & priv->info->flags ? |
| 815 | 0x0001 : 0x0000; | ||
| 810 | 816 | ||
| 811 | ECHECKER(ret, mt9t112_init_camera(client)); | 817 | ECHECKER(ret, mt9t112_init_camera(client)); |
| 812 | 818 | ||
| 813 | /* Invert PCLK (Data sampled on falling edge of pixclk) */ | 819 | /* Invert PCLK (Data sampled on falling edge of pixclk). */ |
| 814 | mt9t112_reg_write(ret, client, 0x3C20, param); | 820 | mt9t112_reg_write(ret, client, 0x3C20, param); |
| 815 | 821 | ||
| 816 | mdelay(5); | 822 | mdelay(5); |
| 817 | 823 | ||
| 818 | priv->flags |= INIT_DONE; | 824 | priv->init_done = true; |
| 819 | } | 825 | } |
| 820 | 826 | ||
| 821 | mt9t112_mcu_write(ret, client, VAR(26, 7), priv->format->fmt); | 827 | mt9t112_mcu_write(ret, client, VAR(26, 7), priv->format->fmt); |
| 822 | mt9t112_mcu_write(ret, client, VAR(26, 9), priv->format->order); | 828 | mt9t112_mcu_write(ret, client, VAR(26, 9), priv->format->order); |
| 823 | mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x06); | 829 | mt9t112_mcu_write(ret, client, VAR8(1, 0), 0x06); |
| 824 | 830 | ||
| 825 | mt9t112_set_a_frame_size(client, | 831 | mt9t112_set_a_frame_size(client, priv->frame.width, priv->frame.height); |
| 826 | priv->frame.width, | ||
| 827 | priv->frame.height); | ||
| 828 | 832 | ||
| 829 | ECHECKER(ret, mt9t112_auto_focus_trigger(client)); | 833 | ECHECKER(ret, mt9t112_auto_focus_trigger(client)); |
| 830 | 834 | ||
| @@ -854,13 +858,13 @@ static int mt9t112_set_params(struct mt9t112_priv *priv, | |||
| 854 | if (i == priv->num_formats) | 858 | if (i == priv->num_formats) |
| 855 | return -EINVAL; | 859 | return -EINVAL; |
| 856 | 860 | ||
| 857 | priv->frame = *rect; | 861 | priv->frame = *rect; |
| 858 | 862 | ||
| 859 | /* | 863 | /* |
| 860 | * frame size check | 864 | * frame size check |
| 861 | */ | 865 | */ |
| 862 | mt9t112_frame_check(&priv->frame.width, &priv->frame.height, | 866 | v4l_bound_align_image(&priv->frame.width, 0, MAX_WIDTH, 0, |
| 863 | &priv->frame.left, &priv->frame.top); | 867 | &priv->frame.height, 0, MAX_HEIGHT, 0, 0); |
| 864 | 868 | ||
| 865 | priv->format = mt9t112_cfmts + i; | 869 | priv->format = mt9t112_cfmts + i; |
| 866 | 870 | ||
| @@ -868,7 +872,7 @@ static int mt9t112_set_params(struct mt9t112_priv *priv, | |||
| 868 | } | 872 | } |
| 869 | 873 | ||
| 870 | static int mt9t112_get_selection(struct v4l2_subdev *sd, | 874 | static int mt9t112_get_selection(struct v4l2_subdev *sd, |
| 871 | struct v4l2_subdev_pad_config *cfg, | 875 | struct v4l2_subdev_pad_config *cfg, |
| 872 | struct v4l2_subdev_selection *sel) | 876 | struct v4l2_subdev_selection *sel) |
| 873 | { | 877 | { |
| 874 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 878 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| @@ -899,8 +903,8 @@ static int mt9t112_get_selection(struct v4l2_subdev *sd, | |||
| 899 | } | 903 | } |
| 900 | 904 | ||
| 901 | static int mt9t112_set_selection(struct v4l2_subdev *sd, | 905 | static int mt9t112_set_selection(struct v4l2_subdev *sd, |
| 902 | struct v4l2_subdev_pad_config *cfg, | 906 | struct v4l2_subdev_pad_config *cfg, |
| 903 | struct v4l2_subdev_selection *sel) | 907 | struct v4l2_subdev_selection *sel) |
| 904 | { | 908 | { |
| 905 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 909 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| 906 | struct mt9t112_priv *priv = to_mt9t112(client); | 910 | struct mt9t112_priv *priv = to_mt9t112(client); |
| @@ -914,8 +918,8 @@ static int mt9t112_set_selection(struct v4l2_subdev *sd, | |||
| 914 | } | 918 | } |
| 915 | 919 | ||
| 916 | static int mt9t112_get_fmt(struct v4l2_subdev *sd, | 920 | static int mt9t112_get_fmt(struct v4l2_subdev *sd, |
| 917 | struct v4l2_subdev_pad_config *cfg, | 921 | struct v4l2_subdev_pad_config *cfg, |
| 918 | struct v4l2_subdev_format *format) | 922 | struct v4l2_subdev_format *format) |
| 919 | { | 923 | { |
| 920 | struct v4l2_mbus_framefmt *mf = &format->format; | 924 | struct v4l2_mbus_framefmt *mf = &format->format; |
| 921 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 925 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| @@ -955,13 +959,12 @@ static int mt9t112_s_fmt(struct v4l2_subdev *sd, | |||
| 955 | } | 959 | } |
| 956 | 960 | ||
| 957 | static int mt9t112_set_fmt(struct v4l2_subdev *sd, | 961 | static int mt9t112_set_fmt(struct v4l2_subdev *sd, |
| 958 | struct v4l2_subdev_pad_config *cfg, | 962 | struct v4l2_subdev_pad_config *cfg, |
| 959 | struct v4l2_subdev_format *format) | 963 | struct v4l2_subdev_format *format) |
| 960 | { | 964 | { |
| 961 | struct v4l2_mbus_framefmt *mf = &format->format; | ||
| 962 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 965 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| 966 | struct v4l2_mbus_framefmt *mf = &format->format; | ||
| 963 | struct mt9t112_priv *priv = to_mt9t112(client); | 967 | struct mt9t112_priv *priv = to_mt9t112(client); |
| 964 | unsigned int top, left; | ||
| 965 | int i; | 968 | int i; |
| 966 | 969 | ||
| 967 | if (format->pad) | 970 | if (format->pad) |
| @@ -975,22 +978,24 @@ static int mt9t112_set_fmt(struct v4l2_subdev *sd, | |||
| 975 | mf->code = MEDIA_BUS_FMT_UYVY8_2X8; | 978 | mf->code = MEDIA_BUS_FMT_UYVY8_2X8; |
| 976 | mf->colorspace = V4L2_COLORSPACE_JPEG; | 979 | mf->colorspace = V4L2_COLORSPACE_JPEG; |
| 977 | } else { | 980 | } else { |
| 978 | mf->colorspace = mt9t112_cfmts[i].colorspace; | 981 | mf->colorspace = mt9t112_cfmts[i].colorspace; |
| 979 | } | 982 | } |
| 980 | 983 | ||
| 981 | mt9t112_frame_check(&mf->width, &mf->height, &left, &top); | 984 | v4l_bound_align_image(&mf->width, 0, MAX_WIDTH, 0, |
| 985 | &mf->height, 0, MAX_HEIGHT, 0, 0); | ||
| 982 | 986 | ||
| 983 | mf->field = V4L2_FIELD_NONE; | 987 | mf->field = V4L2_FIELD_NONE; |
| 984 | 988 | ||
| 985 | if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) | 989 | if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) |
| 986 | return mt9t112_s_fmt(sd, mf); | 990 | return mt9t112_s_fmt(sd, mf); |
| 987 | cfg->try_fmt = *mf; | 991 | cfg->try_fmt = *mf; |
| 992 | |||
| 988 | return 0; | 993 | return 0; |
| 989 | } | 994 | } |
| 990 | 995 | ||
| 991 | static int mt9t112_enum_mbus_code(struct v4l2_subdev *sd, | 996 | static int mt9t112_enum_mbus_code(struct v4l2_subdev *sd, |
| 992 | struct v4l2_subdev_pad_config *cfg, | 997 | struct v4l2_subdev_pad_config *cfg, |
| 993 | struct v4l2_subdev_mbus_code_enum *code) | 998 | struct v4l2_subdev_mbus_code_enum *code) |
| 994 | { | 999 | { |
| 995 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 1000 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
| 996 | struct mt9t112_priv *priv = to_mt9t112(client); | 1001 | struct mt9t112_priv *priv = to_mt9t112(client); |
| @@ -1003,42 +1008,12 @@ static int mt9t112_enum_mbus_code(struct v4l2_subdev *sd, | |||
| 1003 | return 0; | 1008 | return 0; |
| 1004 | } | 1009 | } |
| 1005 | 1010 | ||
| 1006 | static int mt9t112_g_mbus_config(struct v4l2_subdev *sd, | ||
| 1007 | struct v4l2_mbus_config *cfg) | ||
| 1008 | { | ||
| 1009 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
| 1010 | struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); | ||
| 1011 | |||
| 1012 | cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_VSYNC_ACTIVE_HIGH | | ||
| 1013 | V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_DATA_ACTIVE_HIGH | | ||
| 1014 | V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING; | ||
| 1015 | cfg->type = V4L2_MBUS_PARALLEL; | ||
| 1016 | cfg->flags = soc_camera_apply_board_flags(ssdd, cfg); | ||
| 1017 | |||
| 1018 | return 0; | ||
| 1019 | } | ||
| 1020 | |||
| 1021 | static int mt9t112_s_mbus_config(struct v4l2_subdev *sd, | ||
| 1022 | const struct v4l2_mbus_config *cfg) | ||
| 1023 | { | ||
| 1024 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
| 1025 | struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); | ||
| 1026 | struct mt9t112_priv *priv = to_mt9t112(client); | ||
| 1027 | |||
| 1028 | if (soc_camera_apply_board_flags(ssdd, cfg) & V4L2_MBUS_PCLK_SAMPLE_RISING) | ||
| 1029 | priv->flags |= PCLK_RISING; | ||
| 1030 | |||
| 1031 | return 0; | ||
| 1032 | } | ||
| 1033 | |||
| 1034 | static const struct v4l2_subdev_video_ops mt9t112_subdev_video_ops = { | 1011 | static const struct v4l2_subdev_video_ops mt9t112_subdev_video_ops = { |
| 1035 | .s_stream = mt9t112_s_stream, | 1012 | .s_stream = mt9t112_s_stream, |
| 1036 | .g_mbus_config = mt9t112_g_mbus_config, | ||
| 1037 | .s_mbus_config = mt9t112_s_mbus_config, | ||
| 1038 | }; | 1013 | }; |
| 1039 | 1014 | ||
| 1040 | static const struct v4l2_subdev_pad_ops mt9t112_subdev_pad_ops = { | 1015 | static const struct v4l2_subdev_pad_ops mt9t112_subdev_pad_ops = { |
| 1041 | .enum_mbus_code = mt9t112_enum_mbus_code, | 1016 | .enum_mbus_code = mt9t112_enum_mbus_code, |
| 1042 | .get_selection = mt9t112_get_selection, | 1017 | .get_selection = mt9t112_get_selection, |
| 1043 | .set_selection = mt9t112_set_selection, | 1018 | .set_selection = mt9t112_set_selection, |
| 1044 | .get_fmt = mt9t112_get_fmt, | 1019 | .get_fmt = mt9t112_get_fmt, |
| @@ -1046,8 +1021,8 @@ static const struct v4l2_subdev_pad_ops mt9t112_subdev_pad_ops = { | |||
| 1046 | }; | 1021 | }; |
| 1047 | 1022 | ||
| 1048 | /************************************************************************ | 1023 | /************************************************************************ |
| 1049 | i2c driver | 1024 | * i2c driver |
| 1050 | ************************************************************************/ | 1025 | ***********************************************************************/ |
| 1051 | static const struct v4l2_subdev_ops mt9t112_subdev_ops = { | 1026 | static const struct v4l2_subdev_ops mt9t112_subdev_ops = { |
| 1052 | .core = &mt9t112_subdev_core_ops, | 1027 | .core = &mt9t112_subdev_core_ops, |
| 1053 | .video = &mt9t112_subdev_video_ops, | 1028 | .video = &mt9t112_subdev_video_ops, |
| @@ -1065,9 +1040,7 @@ static int mt9t112_camera_probe(struct i2c_client *client) | |||
| 1065 | if (ret < 0) | 1040 | if (ret < 0) |
| 1066 | return ret; | 1041 | return ret; |
| 1067 | 1042 | ||
| 1068 | /* | 1043 | /* Check and show chip ID. */ |
| 1069 | * check and show chip ID | ||
| 1070 | */ | ||
| 1071 | mt9t112_reg_read(chipid, client, 0x0000); | 1044 | mt9t112_reg_read(chipid, client, 0x0000); |
| 1072 | 1045 | ||
| 1073 | switch (chipid) { | 1046 | switch (chipid) { |
| @@ -1089,6 +1062,7 @@ static int mt9t112_camera_probe(struct i2c_client *client) | |||
| 1089 | 1062 | ||
| 1090 | done: | 1063 | done: |
| 1091 | mt9t112_s_power(&priv->subdev, 0); | 1064 | mt9t112_s_power(&priv->subdev, 0); |
| 1065 | |||
| 1092 | return ret; | 1066 | return ret; |
| 1093 | } | 1067 | } |
| 1094 | 1068 | ||
| @@ -1096,16 +1070,9 @@ static int mt9t112_probe(struct i2c_client *client, | |||
| 1096 | const struct i2c_device_id *did) | 1070 | const struct i2c_device_id *did) |
| 1097 | { | 1071 | { |
| 1098 | struct mt9t112_priv *priv; | 1072 | struct mt9t112_priv *priv; |
| 1099 | struct soc_camera_subdev_desc *ssdd = soc_camera_i2c_to_desc(client); | ||
| 1100 | struct v4l2_rect rect = { | ||
| 1101 | .width = VGA_WIDTH, | ||
| 1102 | .height = VGA_HEIGHT, | ||
| 1103 | .left = (MAX_WIDTH - VGA_WIDTH) / 2, | ||
| 1104 | .top = (MAX_HEIGHT - VGA_HEIGHT) / 2, | ||
| 1105 | }; | ||
| 1106 | int ret; | 1073 | int ret; |
| 1107 | 1074 | ||
| 1108 | if (!ssdd || !ssdd->drv_priv) { | 1075 | if (!client->dev.platform_data) { |
| 1109 | dev_err(&client->dev, "mt9t112: missing platform data!\n"); | 1076 | dev_err(&client->dev, "mt9t112: missing platform data!\n"); |
| 1110 | return -EINVAL; | 1077 | return -EINVAL; |
| 1111 | } | 1078 | } |
| @@ -1114,30 +1081,40 @@ static int mt9t112_probe(struct i2c_client *client, | |||
| 1114 | if (!priv) | 1081 | if (!priv) |
| 1115 | return -ENOMEM; | 1082 | return -ENOMEM; |
| 1116 | 1083 | ||
| 1117 | priv->info = ssdd->drv_priv; | 1084 | priv->info = client->dev.platform_data; |
| 1085 | priv->init_done = false; | ||
| 1118 | 1086 | ||
| 1119 | v4l2_i2c_subdev_init(&priv->subdev, client, &mt9t112_subdev_ops); | 1087 | v4l2_i2c_subdev_init(&priv->subdev, client, &mt9t112_subdev_ops); |
| 1120 | 1088 | ||
| 1121 | priv->clk = v4l2_clk_get(&client->dev, "mclk"); | 1089 | priv->clk = devm_clk_get(&client->dev, "extclk"); |
| 1122 | if (IS_ERR(priv->clk)) | 1090 | if (PTR_ERR(priv->clk) == -ENOENT) { |
| 1091 | priv->clk = NULL; | ||
| 1092 | } else if (IS_ERR(priv->clk)) { | ||
| 1093 | dev_err(&client->dev, "Unable to get clock \"extclk\"\n"); | ||
| 1123 | return PTR_ERR(priv->clk); | 1094 | return PTR_ERR(priv->clk); |
| 1095 | } | ||
| 1124 | 1096 | ||
| 1125 | ret = mt9t112_camera_probe(client); | 1097 | priv->standby_gpio = devm_gpiod_get_optional(&client->dev, "standby", |
| 1098 | GPIOD_OUT_HIGH); | ||
| 1099 | if (IS_ERR(priv->standby_gpio)) { | ||
| 1100 | dev_err(&client->dev, "Unable to get gpio \"standby\"\n"); | ||
| 1101 | return PTR_ERR(priv->standby_gpio); | ||
| 1102 | } | ||
| 1126 | 1103 | ||
| 1127 | /* Cannot fail: using the default supported pixel code */ | 1104 | ret = mt9t112_camera_probe(client); |
| 1128 | if (!ret) | 1105 | if (ret) |
| 1129 | mt9t112_set_params(priv, &rect, MEDIA_BUS_FMT_UYVY8_2X8); | 1106 | return ret; |
| 1130 | else | ||
| 1131 | v4l2_clk_put(priv->clk); | ||
| 1132 | 1107 | ||
| 1133 | return ret; | 1108 | return v4l2_async_register_subdev(&priv->subdev); |
| 1134 | } | 1109 | } |
| 1135 | 1110 | ||
| 1136 | static int mt9t112_remove(struct i2c_client *client) | 1111 | static int mt9t112_remove(struct i2c_client *client) |
| 1137 | { | 1112 | { |
| 1138 | struct mt9t112_priv *priv = to_mt9t112(client); | 1113 | struct mt9t112_priv *priv = to_mt9t112(client); |
| 1139 | 1114 | ||
| 1140 | v4l2_clk_put(priv->clk); | 1115 | clk_disable_unprepare(priv->clk); |
| 1116 | v4l2_async_unregister_subdev(&priv->subdev); | ||
| 1117 | |||
| 1141 | return 0; | 1118 | return 0; |
| 1142 | } | 1119 | } |
| 1143 | 1120 | ||
| @@ -1158,6 +1135,6 @@ static struct i2c_driver mt9t112_i2c_driver = { | |||
| 1158 | 1135 | ||
| 1159 | module_i2c_driver(mt9t112_i2c_driver); | 1136 | module_i2c_driver(mt9t112_i2c_driver); |
| 1160 | 1137 | ||
| 1161 | MODULE_DESCRIPTION("SoC Camera driver for mt9t112"); | 1138 | MODULE_DESCRIPTION("V4L2 driver for MT9T111/MT9T112 camera sensor"); |
| 1162 | MODULE_AUTHOR("Kuninori Morimoto"); | 1139 | MODULE_AUTHOR("Kuninori Morimoto"); |
| 1163 | MODULE_LICENSE("GPL v2"); | 1140 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/media/i2c/soc_camera/mt9t112.c b/drivers/media/i2c/soc_camera/mt9t112.c index 297d22ebcb18..b53c36dfa469 100644 --- a/drivers/media/i2c/soc_camera/mt9t112.c +++ b/drivers/media/i2c/soc_camera/mt9t112.c | |||
| @@ -85,7 +85,7 @@ struct mt9t112_format { | |||
| 85 | 85 | ||
| 86 | struct mt9t112_priv { | 86 | struct mt9t112_priv { |
| 87 | struct v4l2_subdev subdev; | 87 | struct v4l2_subdev subdev; |
| 88 | struct mt9t112_camera_info *info; | 88 | struct mt9t112_platform_data *info; |
| 89 | struct i2c_client *client; | 89 | struct i2c_client *client; |
| 90 | struct v4l2_rect frame; | 90 | struct v4l2_rect frame; |
| 91 | struct v4l2_clk *clk; | 91 | struct v4l2_clk *clk; |
diff --git a/include/media/i2c/mt9t112.h b/include/media/i2c/mt9t112.h index a43c74ab05ec..cc80d5cc2104 100644 --- a/include/media/i2c/mt9t112.h +++ b/include/media/i2c/mt9t112.h | |||
| @@ -1,28 +1,25 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
| 1 | /* mt9t112 Camera | 2 | /* mt9t112 Camera |
| 2 | * | 3 | * |
| 3 | * Copyright (C) 2009 Renesas Solutions Corp. | 4 | * Copyright (C) 2009 Renesas Solutions Corp. |
| 4 | * Kuninori Morimoto <morimoto.kuninori@renesas.com> | 5 | * Kuninori Morimoto <morimoto.kuninori@renesas.com> |
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License version 2 as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | */ | 6 | */ |
| 10 | 7 | ||
| 11 | #ifndef __MT9T112_H__ | 8 | #ifndef __MT9T112_H__ |
| 12 | #define __MT9T112_H__ | 9 | #define __MT9T112_H__ |
| 13 | 10 | ||
| 14 | #define MT9T112_FLAG_PCLK_RISING_EDGE (1 << 0) | ||
| 15 | #define MT9T112_FLAG_DATAWIDTH_8 (1 << 1) /* default width is 10 */ | ||
| 16 | |||
| 17 | struct mt9t112_pll_divider { | 11 | struct mt9t112_pll_divider { |
| 18 | u8 m, n; | 12 | u8 m, n; |
| 19 | u8 p1, p2, p3, p4, p5, p6, p7; | 13 | u8 p1, p2, p3, p4, p5, p6, p7; |
| 20 | }; | 14 | }; |
| 21 | 15 | ||
| 22 | /* | 16 | /** |
| 23 | * mt9t112 camera info | 17 | * mt9t112_platform_data - mt9t112 driver interface |
| 18 | * @flags: Sensor media bus configuration. | ||
| 19 | * @divider: Sensor PLL configuration | ||
| 24 | */ | 20 | */ |
| 25 | struct mt9t112_camera_info { | 21 | struct mt9t112_platform_data { |
| 22 | #define MT9T112_FLAG_PCLK_RISING_EDGE BIT(0) | ||
| 26 | u32 flags; | 23 | u32 flags; |
| 27 | struct mt9t112_pll_divider divider; | 24 | struct mt9t112_pll_divider divider; |
| 28 | }; | 25 | }; |
