aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2009-10-03 07:21:30 -0400
committerPaul Mundt <lethal@linux-sh.org>2009-10-10 08:21:59 -0400
commita469f627c15de2af392be23508e6094d7268e2b7 (patch)
tree7d76e3b95f80d1b61437b4a06284c633615fa988 /arch/sh
parentbd381934bf13ccb1af2813ae26c6fe00ec85d254 (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.c139
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
217static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
218 .flags = SH_CEU_FLAG_USE_8BIT_BUS,
219};
220
221static 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
238static 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
251static struct i2c_board_info kfr2r09_i2c_camera = {
252 I2C_BOARD_INFO("rj54n1cb0c", 0x50),
253};
254
255static struct clk *camera_clk;
256
257#define DRVCRB 0xA405018C
258static 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);
307eclkon:
308 gpio_set_value(GPIO_PTB7, 0);
309egpioout:
310 gpio_set_value(GPIO_PTB4, 0);
311 gpio_free(GPIO_PTB7);
312eptb7:
313 gpio_free(GPIO_PTB4);
314eptb4:
315eclkrate:
316 clk_put(camera_clk);
317 return ret;
318}
319
320static 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
327static struct platform_device kfr2r09_camera = {
328 .name = "soc-camera-pdrv",
329 .id = 0,
330 .dev = {
331 .platform_data = &rj54n1_link,
332 },
333};
334
215static struct platform_device *kfr2r09_devices[] __initdata = { 335static 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}