diff options
author | Guennadi Liakhovetski <g.liakhovetski@gmx.de> | 2009-10-03 07:21:30 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2009-10-10 08:21:59 -0400 |
commit | a469f627c15de2af392be23508e6094d7268e2b7 (patch) | |
tree | 7d76e3b95f80d1b61437b4a06284c633615fa988 /arch/sh | |
parent | bd381934bf13ccb1af2813ae26c6fe00ec85d254 (diff) |
SH: add support for the RJ54N1CB0C camera for the kfr2r09 platform
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh')
-rw-r--r-- | arch/sh/boards/mach-kfr2r09/setup.c | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c index c08d33fe2104..ce01d6a953b8 100644 --- a/arch/sh/boards/mach-kfr2r09/setup.c +++ b/arch/sh/boards/mach-kfr2r09/setup.c | |||
@@ -18,6 +18,8 @@ | |||
18 | #include <linux/input.h> | 18 | #include <linux/input.h> |
19 | #include <linux/i2c.h> | 19 | #include <linux/i2c.h> |
20 | #include <linux/usb/r8a66597.h> | 20 | #include <linux/usb/r8a66597.h> |
21 | #include <media/soc_camera.h> | ||
22 | #include <media/sh_mobile_ceu.h> | ||
21 | #include <video/sh_mobile_lcdc.h> | 23 | #include <video/sh_mobile_lcdc.h> |
22 | #include <asm/clock.h> | 24 | #include <asm/clock.h> |
23 | #include <asm/machvec.h> | 25 | #include <asm/machvec.h> |
@@ -212,11 +214,131 @@ static struct platform_device kfr2r09_usb0_gadget_device = { | |||
212 | .resource = kfr2r09_usb0_gadget_resources, | 214 | .resource = kfr2r09_usb0_gadget_resources, |
213 | }; | 215 | }; |
214 | 216 | ||
217 | static struct sh_mobile_ceu_info sh_mobile_ceu_info = { | ||
218 | .flags = SH_CEU_FLAG_USE_8BIT_BUS, | ||
219 | }; | ||
220 | |||
221 | static struct resource kfr2r09_ceu_resources[] = { | ||
222 | [0] = { | ||
223 | .name = "CEU", | ||
224 | .start = 0xfe910000, | ||
225 | .end = 0xfe91009f, | ||
226 | .flags = IORESOURCE_MEM, | ||
227 | }, | ||
228 | [1] = { | ||
229 | .start = 52, | ||
230 | .end = 52, | ||
231 | .flags = IORESOURCE_IRQ, | ||
232 | }, | ||
233 | [2] = { | ||
234 | /* place holder for contiguous memory */ | ||
235 | }, | ||
236 | }; | ||
237 | |||
238 | static struct platform_device kfr2r09_ceu_device = { | ||
239 | .name = "sh_mobile_ceu", | ||
240 | .id = 0, /* "ceu0" clock */ | ||
241 | .num_resources = ARRAY_SIZE(kfr2r09_ceu_resources), | ||
242 | .resource = kfr2r09_ceu_resources, | ||
243 | .dev = { | ||
244 | .platform_data = &sh_mobile_ceu_info, | ||
245 | }, | ||
246 | .archdata = { | ||
247 | .hwblk_id = HWBLK_CEU0, | ||
248 | }, | ||
249 | }; | ||
250 | |||
251 | static struct i2c_board_info kfr2r09_i2c_camera = { | ||
252 | I2C_BOARD_INFO("rj54n1cb0c", 0x50), | ||
253 | }; | ||
254 | |||
255 | static struct clk *camera_clk; | ||
256 | |||
257 | #define DRVCRB 0xA405018C | ||
258 | static int camera_power(struct device *dev, int mode) | ||
259 | { | ||
260 | int ret; | ||
261 | |||
262 | if (mode) { | ||
263 | long rate; | ||
264 | |||
265 | camera_clk = clk_get(NULL, "video_clk"); | ||
266 | if (IS_ERR(camera_clk)) | ||
267 | return PTR_ERR(camera_clk); | ||
268 | |||
269 | /* set VIO_CKO clock to 25MHz */ | ||
270 | rate = clk_round_rate(camera_clk, 25000000); | ||
271 | ret = clk_set_rate(camera_clk, rate); | ||
272 | if (ret < 0) | ||
273 | goto eclkrate; | ||
274 | |||
275 | /* set DRVCRB | ||
276 | * | ||
277 | * use 1.8 V for VccQ_VIO | ||
278 | * use 2.85V for VccQ_SR | ||
279 | */ | ||
280 | ctrl_outw((ctrl_inw(DRVCRB) & ~0x0003) | 0x0001, DRVCRB); | ||
281 | |||
282 | /* reset clear */ | ||
283 | ret = gpio_request(GPIO_PTB4, NULL); | ||
284 | if (ret < 0) | ||
285 | goto eptb4; | ||
286 | ret = gpio_request(GPIO_PTB7, NULL); | ||
287 | if (ret < 0) | ||
288 | goto eptb7; | ||
289 | |||
290 | ret = gpio_direction_output(GPIO_PTB4, 1); | ||
291 | if (!ret) | ||
292 | ret = gpio_direction_output(GPIO_PTB7, 1); | ||
293 | if (ret < 0) | ||
294 | goto egpioout; | ||
295 | msleep(1); | ||
296 | |||
297 | ret = clk_enable(camera_clk); /* start VIO_CKO */ | ||
298 | if (ret < 0) | ||
299 | goto eclkon; | ||
300 | |||
301 | return 0; | ||
302 | } | ||
303 | |||
304 | ret = 0; | ||
305 | |||
306 | clk_disable(camera_clk); | ||
307 | eclkon: | ||
308 | gpio_set_value(GPIO_PTB7, 0); | ||
309 | egpioout: | ||
310 | gpio_set_value(GPIO_PTB4, 0); | ||
311 | gpio_free(GPIO_PTB7); | ||
312 | eptb7: | ||
313 | gpio_free(GPIO_PTB4); | ||
314 | eptb4: | ||
315 | eclkrate: | ||
316 | clk_put(camera_clk); | ||
317 | return ret; | ||
318 | } | ||
319 | |||
320 | static struct soc_camera_link rj54n1_link = { | ||
321 | .power = camera_power, | ||
322 | .board_info = &kfr2r09_i2c_camera, | ||
323 | .i2c_adapter_id = 1, | ||
324 | .module_name = "rj54n1cb0c", | ||
325 | }; | ||
326 | |||
327 | static struct platform_device kfr2r09_camera = { | ||
328 | .name = "soc-camera-pdrv", | ||
329 | .id = 0, | ||
330 | .dev = { | ||
331 | .platform_data = &rj54n1_link, | ||
332 | }, | ||
333 | }; | ||
334 | |||
215 | static struct platform_device *kfr2r09_devices[] __initdata = { | 335 | static struct platform_device *kfr2r09_devices[] __initdata = { |
216 | &kfr2r09_nor_flash_device, | 336 | &kfr2r09_nor_flash_device, |
217 | &kfr2r09_nand_flash_device, | 337 | &kfr2r09_nand_flash_device, |
218 | &kfr2r09_sh_keysc_device, | 338 | &kfr2r09_sh_keysc_device, |
219 | &kfr2r09_sh_lcdc_device, | 339 | &kfr2r09_sh_lcdc_device, |
340 | &kfr2r09_ceu_device, | ||
341 | &kfr2r09_camera, | ||
220 | }; | 342 | }; |
221 | 343 | ||
222 | #define BSC_CS0BCR 0xfec10004 | 344 | #define BSC_CS0BCR 0xfec10004 |
@@ -361,6 +483,23 @@ static int __init kfr2r09_devices_setup(void) | |||
361 | if (kfr2r09_usb0_gadget_setup() == 0) | 483 | if (kfr2r09_usb0_gadget_setup() == 0) |
362 | platform_device_register(&kfr2r09_usb0_gadget_device); | 484 | platform_device_register(&kfr2r09_usb0_gadget_device); |
363 | 485 | ||
486 | /* CEU */ | ||
487 | gpio_request(GPIO_FN_VIO_CKO, NULL); | ||
488 | gpio_request(GPIO_FN_VIO0_CLK, NULL); | ||
489 | gpio_request(GPIO_FN_VIO0_VD, NULL); | ||
490 | gpio_request(GPIO_FN_VIO0_HD, NULL); | ||
491 | gpio_request(GPIO_FN_VIO0_FLD, NULL); | ||
492 | gpio_request(GPIO_FN_VIO0_D7, NULL); | ||
493 | gpio_request(GPIO_FN_VIO0_D6, NULL); | ||
494 | gpio_request(GPIO_FN_VIO0_D5, NULL); | ||
495 | gpio_request(GPIO_FN_VIO0_D4, NULL); | ||
496 | gpio_request(GPIO_FN_VIO0_D3, NULL); | ||
497 | gpio_request(GPIO_FN_VIO0_D2, NULL); | ||
498 | gpio_request(GPIO_FN_VIO0_D1, NULL); | ||
499 | gpio_request(GPIO_FN_VIO0_D0, NULL); | ||
500 | |||
501 | platform_resource_setup_memory(&kfr2r09_ceu_device, "ceu", 4 << 20); | ||
502 | |||
364 | return platform_add_devices(kfr2r09_devices, | 503 | return platform_add_devices(kfr2r09_devices, |
365 | ARRAY_SIZE(kfr2r09_devices)); | 504 | ARRAY_SIZE(kfr2r09_devices)); |
366 | } | 505 | } |