diff options
Diffstat (limited to 'drivers/media/usb')
-rw-r--r-- | drivers/media/usb/em28xx/em28xx-cards.c | 122 |
1 files changed, 72 insertions, 50 deletions
diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index c1397db7c145..de15cdff5892 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c | |||
@@ -2335,50 +2335,14 @@ static int em28xx_hint_sensor(struct em28xx *dev) | |||
2335 | case 0x8243: /* mt9v011 rev B 640x480 1.3 Mpix sensor */ | 2335 | case 0x8243: /* mt9v011 rev B 640x480 1.3 Mpix sensor */ |
2336 | sensor_name = "mt9v011"; | 2336 | sensor_name = "mt9v011"; |
2337 | dev->em28xx_sensor = EM28XX_MT9V011; | 2337 | dev->em28xx_sensor = EM28XX_MT9V011; |
2338 | dev->sensor_xres = 640; | ||
2339 | dev->sensor_yres = 480; | ||
2340 | /* | ||
2341 | * FIXME: mt9v011 uses I2S speed as xtal clk - at least with | ||
2342 | * the Silvercrest cam I have here for testing - for higher | ||
2343 | * resolutions, a high clock cause horizontal artifacts, so we | ||
2344 | * need to use a lower xclk frequency. | ||
2345 | * Yet, it would be possible to adjust xclk depending on the | ||
2346 | * desired resolution, since this affects directly the | ||
2347 | * frame rate. | ||
2348 | */ | ||
2349 | dev->board.xclk = EM28XX_XCLK_FREQUENCY_4_3MHZ; | ||
2350 | dev->sensor_xtal = 4300000; | ||
2351 | |||
2352 | /* probably means GRGB 16 bit bayer */ | ||
2353 | dev->vinmode = 0x0d; | ||
2354 | dev->vinctl = 0x00; | ||
2355 | |||
2356 | break; | 2338 | break; |
2357 | |||
2358 | case 0x143a: /* MT9M111 as found in the ECS G200 */ | 2339 | case 0x143a: /* MT9M111 as found in the ECS G200 */ |
2359 | sensor_name = "mt9m111"; | 2340 | sensor_name = "mt9m111"; |
2360 | dev->board.xclk = EM28XX_XCLK_FREQUENCY_48MHZ; | ||
2361 | dev->em28xx_sensor = EM28XX_MT9M111; | 2341 | dev->em28xx_sensor = EM28XX_MT9M111; |
2362 | em28xx_initialize_mt9m111(dev); | ||
2363 | dev->sensor_xres = 640; | ||
2364 | dev->sensor_yres = 512; | ||
2365 | |||
2366 | dev->vinmode = 0x0a; | ||
2367 | dev->vinctl = 0x00; | ||
2368 | |||
2369 | break; | 2342 | break; |
2370 | |||
2371 | case 0x8431: | 2343 | case 0x8431: |
2372 | sensor_name = "mt9m001"; | 2344 | sensor_name = "mt9m001"; |
2373 | dev->em28xx_sensor = EM28XX_MT9M001; | 2345 | dev->em28xx_sensor = EM28XX_MT9M001; |
2374 | em28xx_initialize_mt9m001(dev); | ||
2375 | dev->sensor_xres = 1280; | ||
2376 | dev->sensor_yres = 1024; | ||
2377 | |||
2378 | /* probably means BGGR 16 bit bayer */ | ||
2379 | dev->vinmode = 0x0c; | ||
2380 | dev->vinctl = 0x00; | ||
2381 | |||
2382 | break; | 2346 | break; |
2383 | default: | 2347 | default: |
2384 | printk("Unknown Micron Sensor 0x%04x\n", version); | 2348 | printk("Unknown Micron Sensor 0x%04x\n", version); |
@@ -2611,6 +2575,76 @@ static void em28xx_tuner_setup(struct em28xx *dev) | |||
2611 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f); | 2575 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f); |
2612 | } | 2576 | } |
2613 | 2577 | ||
2578 | static int em28xx_init_camera(struct em28xx *dev) | ||
2579 | { | ||
2580 | switch (dev->em28xx_sensor) { | ||
2581 | case EM28XX_MT9V011: | ||
2582 | { | ||
2583 | struct mt9v011_platform_data pdata; | ||
2584 | struct i2c_board_info mt9v011_info = { | ||
2585 | .type = "mt9v011", | ||
2586 | .addr = dev->i2c_client[dev->def_i2c_bus].addr, | ||
2587 | .platform_data = &pdata, | ||
2588 | }; | ||
2589 | |||
2590 | dev->sensor_xres = 640; | ||
2591 | dev->sensor_yres = 480; | ||
2592 | |||
2593 | /* | ||
2594 | * FIXME: mt9v011 uses I2S speed as xtal clk - at least with | ||
2595 | * the Silvercrest cam I have here for testing - for higher | ||
2596 | * resolutions, a high clock cause horizontal artifacts, so we | ||
2597 | * need to use a lower xclk frequency. | ||
2598 | * Yet, it would be possible to adjust xclk depending on the | ||
2599 | * desired resolution, since this affects directly the | ||
2600 | * frame rate. | ||
2601 | */ | ||
2602 | dev->board.xclk = EM28XX_XCLK_FREQUENCY_4_3MHZ; | ||
2603 | em28xx_write_reg(dev, EM28XX_R0F_XCLK, dev->board.xclk); | ||
2604 | dev->sensor_xtal = 4300000; | ||
2605 | pdata.xtal = dev->sensor_xtal; | ||
2606 | if (NULL == | ||
2607 | v4l2_i2c_new_subdev_board(&dev->v4l2_dev, | ||
2608 | &dev->i2c_adap[dev->def_i2c_bus], | ||
2609 | &mt9v011_info, NULL)) | ||
2610 | return -ENODEV; | ||
2611 | /* probably means GRGB 16 bit bayer */ | ||
2612 | dev->vinmode = 0x0d; | ||
2613 | dev->vinctl = 0x00; | ||
2614 | |||
2615 | break; | ||
2616 | } | ||
2617 | case EM28XX_MT9M001: | ||
2618 | dev->sensor_xres = 1280; | ||
2619 | dev->sensor_yres = 1024; | ||
2620 | |||
2621 | em28xx_initialize_mt9m001(dev); | ||
2622 | |||
2623 | /* probably means BGGR 16 bit bayer */ | ||
2624 | dev->vinmode = 0x0c; | ||
2625 | dev->vinctl = 0x00; | ||
2626 | |||
2627 | break; | ||
2628 | case EM28XX_MT9M111: | ||
2629 | dev->sensor_xres = 640; | ||
2630 | dev->sensor_yres = 512; | ||
2631 | |||
2632 | dev->board.xclk = EM28XX_XCLK_FREQUENCY_48MHZ; | ||
2633 | em28xx_write_reg(dev, EM28XX_R0F_XCLK, dev->board.xclk); | ||
2634 | em28xx_initialize_mt9m111(dev); | ||
2635 | |||
2636 | dev->vinmode = 0x0a; | ||
2637 | dev->vinctl = 0x00; | ||
2638 | |||
2639 | break; | ||
2640 | case EM28XX_NOSENSOR: | ||
2641 | default: | ||
2642 | return -EINVAL; | ||
2643 | } | ||
2644 | |||
2645 | return 0; | ||
2646 | } | ||
2647 | |||
2614 | static int em28xx_hint_board(struct em28xx *dev) | 2648 | static int em28xx_hint_board(struct em28xx *dev) |
2615 | { | 2649 | { |
2616 | int i; | 2650 | int i; |
@@ -2878,20 +2912,6 @@ static void em28xx_card_setup(struct em28xx *dev) | |||
2878 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus], | 2912 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus], |
2879 | "tvp5150", 0, tvp5150_addrs); | 2913 | "tvp5150", 0, tvp5150_addrs); |
2880 | 2914 | ||
2881 | if (dev->em28xx_sensor == EM28XX_MT9V011) { | ||
2882 | struct mt9v011_platform_data pdata; | ||
2883 | struct i2c_board_info mt9v011_info = { | ||
2884 | .type = "mt9v011", | ||
2885 | .addr = 0xba >> 1, | ||
2886 | .platform_data = &pdata, | ||
2887 | }; | ||
2888 | |||
2889 | pdata.xtal = dev->sensor_xtal; | ||
2890 | v4l2_i2c_new_subdev_board(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus], | ||
2891 | &mt9v011_info, NULL); | ||
2892 | } | ||
2893 | |||
2894 | |||
2895 | if (dev->board.adecoder == EM28XX_TVAUDIO) | 2915 | if (dev->board.adecoder == EM28XX_TVAUDIO) |
2896 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus], | 2916 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap[dev->def_i2c_bus], |
2897 | "tvaudio", dev->board.tvaudio_addr, NULL); | 2917 | "tvaudio", dev->board.tvaudio_addr, NULL); |
@@ -2925,6 +2945,8 @@ static void em28xx_card_setup(struct em28xx *dev) | |||
2925 | } | 2945 | } |
2926 | 2946 | ||
2927 | em28xx_tuner_setup(dev); | 2947 | em28xx_tuner_setup(dev); |
2948 | |||
2949 | em28xx_init_camera(dev); | ||
2928 | } | 2950 | } |
2929 | 2951 | ||
2930 | 2952 | ||