aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/tcm825x.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/tcm825x.c')
-rw-r--r--drivers/media/video/tcm825x.c128
1 files changed, 57 insertions, 71 deletions
diff --git a/drivers/media/video/tcm825x.c b/drivers/media/video/tcm825x.c
index 3a139f288a9d..41cd6a0b0485 100644
--- a/drivers/media/video/tcm825x.c
+++ b/drivers/media/video/tcm825x.c
@@ -470,46 +470,6 @@ static int tcm825x_configure(struct v4l2_int_device *s)
470 return 0; 470 return 0;
471} 471}
472 472
473/*
474 * Given the image capture format in pix, the nominal frame period in
475 * timeperframe, calculate the required xclk frequency.
476 *
477 * TCM825X input frequency characteristics are:
478 * Minimum 11.9 MHz, Typical 24.57 MHz and maximum 25/27 MHz
479 */
480#define XCLK_MIN 11900000
481#define XCLK_MAX 25000000
482
483static int ioctl_g_ext_clk(struct v4l2_int_device *s, u32 *xclk)
484{
485 struct tcm825x_sensor *sensor = s->priv;
486 struct v4l2_fract *timeperframe = &sensor->timeperframe;
487 u32 tgt_xclk; /* target xclk */
488 u32 tgt_fps; /* target frames per secound */
489
490 tgt_fps = timeperframe->denominator / timeperframe->numerator;
491
492 tgt_xclk = (tgt_fps <= HIGH_FPS_MODE_LOWER_LIMIT) ?
493 (2457 * tgt_fps) / MAX_HALF_FPS :
494 (2457 * tgt_fps) / MAX_FPS;
495 tgt_xclk *= 10000;
496
497 tgt_xclk = min(tgt_xclk, (u32)XCLK_MAX);
498 tgt_xclk = max(tgt_xclk, (u32)XCLK_MIN);
499
500 *xclk = tgt_xclk;
501
502 return 0;
503}
504
505static int ioctl_s_ext_clk(struct v4l2_int_device *s, u32 xclk)
506{
507 if (xclk > XCLK_MAX || xclk < XCLK_MIN)
508 return -EINVAL;
509
510 return 0;
511}
512
513static int ioctl_queryctrl(struct v4l2_int_device *s, 473static int ioctl_queryctrl(struct v4l2_int_device *s,
514 struct v4l2_queryctrl *qc) 474 struct v4l2_queryctrl *qc)
515{ 475{
@@ -756,6 +716,41 @@ static int ioctl_s_power(struct v4l2_int_device *s, int on)
756 return sensor->platform_data->power_set(on); 716 return sensor->platform_data->power_set(on);
757} 717}
758 718
719/*
720 * Given the image capture format in pix, the nominal frame period in
721 * timeperframe, calculate the required xclk frequency.
722 *
723 * TCM825X input frequency characteristics are:
724 * Minimum 11.9 MHz, Typical 24.57 MHz and maximum 25/27 MHz
725 */
726
727static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
728{
729 struct tcm825x_sensor *sensor = s->priv;
730 struct v4l2_fract *timeperframe = &sensor->timeperframe;
731 u32 tgt_xclk; /* target xclk */
732 u32 tgt_fps; /* target frames per secound */
733 int rval;
734
735 rval = sensor->platform_data->ifparm(p);
736 if (rval)
737 return rval;
738
739 tgt_fps = timeperframe->denominator / timeperframe->numerator;
740
741 tgt_xclk = (tgt_fps <= HIGH_FPS_MODE_LOWER_LIMIT) ?
742 (2457 * tgt_fps) / MAX_HALF_FPS :
743 (2457 * tgt_fps) / MAX_FPS;
744 tgt_xclk *= 10000;
745
746 tgt_xclk = min(tgt_xclk, (u32)TCM825X_XCLK_MAX);
747 tgt_xclk = max(tgt_xclk, (u32)TCM825X_XCLK_MIN);
748
749 p->u.bt656.clock_curr = tgt_xclk;
750
751 return 0;
752}
753
759static int ioctl_g_needs_reset(struct v4l2_int_device *s, void *buf) 754static int ioctl_g_needs_reset(struct v4l2_int_device *s, void *buf)
760{ 755{
761 struct tcm825x_sensor *sensor = s->priv; 756 struct tcm825x_sensor *sensor = s->priv;
@@ -793,43 +788,39 @@ static int ioctl_dev_init(struct v4l2_int_device *s)
793 return 0; 788 return 0;
794} 789}
795 790
796#define NUM_IOCTLS 17 791static struct v4l2_int_ioctl_desc tcm825x_ioctl_desc[] = {
797
798static struct v4l2_int_ioctl_desc tcm825x_ioctl_desc[NUM_IOCTLS] = {
799 { vidioc_int_dev_init_num, 792 { vidioc_int_dev_init_num,
800 (v4l2_int_ioctl_func *)&ioctl_dev_init }, 793 (v4l2_int_ioctl_func *)ioctl_dev_init },
801 { vidioc_int_dev_exit_num, 794 { vidioc_int_dev_exit_num,
802 (v4l2_int_ioctl_func *)&ioctl_dev_exit }, 795 (v4l2_int_ioctl_func *)ioctl_dev_exit },
803 { vidioc_int_s_power_num, 796 { vidioc_int_s_power_num,
804 (v4l2_int_ioctl_func *)&ioctl_s_power }, 797 (v4l2_int_ioctl_func *)ioctl_s_power },
805 { vidioc_int_g_ext_clk_num, 798 { vidioc_int_g_ifparm_num,
806 (v4l2_int_ioctl_func *)&ioctl_g_ext_clk }, 799 (v4l2_int_ioctl_func *)ioctl_g_ifparm },
807 { vidioc_int_s_ext_clk_num,
808 (v4l2_int_ioctl_func *)&ioctl_s_ext_clk },
809 { vidioc_int_g_needs_reset_num, 800 { vidioc_int_g_needs_reset_num,
810 (v4l2_int_ioctl_func *)&ioctl_g_needs_reset }, 801 (v4l2_int_ioctl_func *)ioctl_g_needs_reset },
811 { vidioc_int_reset_num, 802 { vidioc_int_reset_num,
812 (v4l2_int_ioctl_func *)&ioctl_reset }, 803 (v4l2_int_ioctl_func *)ioctl_reset },
813 { vidioc_int_init_num, 804 { vidioc_int_init_num,
814 (v4l2_int_ioctl_func *)&ioctl_init }, 805 (v4l2_int_ioctl_func *)ioctl_init },
815 { vidioc_int_enum_fmt_cap_num, 806 { vidioc_int_enum_fmt_cap_num,
816 (v4l2_int_ioctl_func *)&ioctl_enum_fmt_cap }, 807 (v4l2_int_ioctl_func *)ioctl_enum_fmt_cap },
817 { vidioc_int_try_fmt_cap_num, 808 { vidioc_int_try_fmt_cap_num,
818 (v4l2_int_ioctl_func *)&ioctl_try_fmt_cap }, 809 (v4l2_int_ioctl_func *)ioctl_try_fmt_cap },
819 { vidioc_int_g_fmt_cap_num, 810 { vidioc_int_g_fmt_cap_num,
820 (v4l2_int_ioctl_func *)&ioctl_g_fmt_cap }, 811 (v4l2_int_ioctl_func *)ioctl_g_fmt_cap },
821 { vidioc_int_s_fmt_cap_num, 812 { vidioc_int_s_fmt_cap_num,
822 (v4l2_int_ioctl_func *)&ioctl_s_fmt_cap }, 813 (v4l2_int_ioctl_func *)ioctl_s_fmt_cap },
823 { vidioc_int_g_parm_num, 814 { vidioc_int_g_parm_num,
824 (v4l2_int_ioctl_func *)&ioctl_g_parm }, 815 (v4l2_int_ioctl_func *)ioctl_g_parm },
825 { vidioc_int_s_parm_num, 816 { vidioc_int_s_parm_num,
826 (v4l2_int_ioctl_func *)&ioctl_s_parm }, 817 (v4l2_int_ioctl_func *)ioctl_s_parm },
827 { vidioc_int_queryctrl_num, 818 { vidioc_int_queryctrl_num,
828 (v4l2_int_ioctl_func *)&ioctl_queryctrl }, 819 (v4l2_int_ioctl_func *)ioctl_queryctrl },
829 { vidioc_int_g_ctrl_num, 820 { vidioc_int_g_ctrl_num,
830 (v4l2_int_ioctl_func *)&ioctl_g_ctrl }, 821 (v4l2_int_ioctl_func *)ioctl_g_ctrl },
831 { vidioc_int_s_ctrl_num, 822 { vidioc_int_s_ctrl_num,
832 (v4l2_int_ioctl_func *)&ioctl_s_ctrl }, 823 (v4l2_int_ioctl_func *)ioctl_s_ctrl },
833}; 824};
834 825
835static struct v4l2_int_slave tcm825x_slave = { 826static struct v4l2_int_slave tcm825x_slave = {
@@ -894,16 +885,16 @@ static int __exit tcm825x_remove(struct i2c_client *client)
894} 885}
895 886
896static struct i2c_driver tcm825x_i2c_driver = { 887static struct i2c_driver tcm825x_i2c_driver = {
897 .driver = { 888 .driver = {
898 .name = TCM825X_NAME, 889 .name = TCM825X_NAME,
899 }, 890 },
900 .probe = &tcm825x_probe, 891 .probe = tcm825x_probe,
901 .remove = __exit_p(&tcm825x_remove), 892 .remove = __exit_p(tcm825x_remove),
902}; 893};
903 894
904static struct tcm825x_sensor tcm825x = { 895static struct tcm825x_sensor tcm825x = {
905 .timeperframe = { 896 .timeperframe = {
906 .numerator = 1, 897 .numerator = 1,
907 .denominator = DEFAULT_FPS, 898 .denominator = DEFAULT_FPS,
908 }, 899 },
909}; 900};
@@ -911,11 +902,6 @@ static struct tcm825x_sensor tcm825x = {
911static int __init tcm825x_init(void) 902static int __init tcm825x_init(void)
912{ 903{
913 int rval; 904 int rval;
914 int i = 0;
915
916 /* Just an experiment --- don't use *_cb functions yet. */
917 tcm825x_ioctl_desc[i++] = vidioc_int_dev_init_cb(&ioctl_dev_init);
918 BUG_ON(i >= NUM_IOCTLS);
919 905
920 rval = i2c_add_driver(&tcm825x_i2c_driver); 906 rval = i2c_add_driver(&tcm825x_i2c_driver);
921 if (rval) 907 if (rval)