aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/mt9p031.c
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2012-02-25 11:25:57 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-03-19 17:54:22 -0400
commit08cd43cc4623c13aa0bf4efa39d087dbe53418e7 (patch)
tree1a4395ae73e91bdd1cc4cb4ad4e01d0044c02fdb /drivers/media/video/mt9p031.c
parent0b27c81ba32de6f5eb9df769d839bab399c4c6de (diff)
[media] mt9p031: Use generic PLL setup code
Compute the PLL parameters at runtime using the generic Aptina PLL helper. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Acked-by: Sakari Ailus <sakari.ailus@iki.fi> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/mt9p031.c')
-rw-r--r--drivers/media/video/mt9p031.c62
1 files changed, 27 insertions, 35 deletions
diff --git a/drivers/media/video/mt9p031.c b/drivers/media/video/mt9p031.c
index 490a38c61f93..c81eaf4fbe01 100644
--- a/drivers/media/video/mt9p031.c
+++ b/drivers/media/video/mt9p031.c
@@ -27,6 +27,8 @@
27#include <media/v4l2-device.h> 27#include <media/v4l2-device.h>
28#include <media/v4l2-subdev.h> 28#include <media/v4l2-subdev.h>
29 29
30#include "aptina-pll.h"
31
30#define MT9P031_PIXEL_ARRAY_WIDTH 2752 32#define MT9P031_PIXEL_ARRAY_WIDTH 2752
31#define MT9P031_PIXEL_ARRAY_HEIGHT 2004 33#define MT9P031_PIXEL_ARRAY_HEIGHT 2004
32 34
@@ -97,14 +99,6 @@
97#define MT9P031_TEST_PATTERN_RED 0xa2 99#define MT9P031_TEST_PATTERN_RED 0xa2
98#define MT9P031_TEST_PATTERN_BLUE 0xa3 100#define MT9P031_TEST_PATTERN_BLUE 0xa3
99 101
100struct mt9p031_pll_divs {
101 u32 ext_freq;
102 u32 target_freq;
103 u8 m;
104 u8 n;
105 u8 p1;
106};
107
108struct mt9p031 { 102struct mt9p031 {
109 struct v4l2_subdev subdev; 103 struct v4l2_subdev subdev;
110 struct media_pad pad; 104 struct media_pad pad;
@@ -115,7 +109,7 @@ struct mt9p031 {
115 struct mutex power_lock; /* lock to protect power_count */ 109 struct mutex power_lock; /* lock to protect power_count */
116 int power_count; 110 int power_count;
117 111
118 const struct mt9p031_pll_divs *pll; 112 struct aptina_pll pll;
119 113
120 /* Registers cache */ 114 /* Registers cache */
121 u16 output_control; 115 u16 output_control;
@@ -183,33 +177,31 @@ static int mt9p031_reset(struct mt9p031 *mt9p031)
183 0); 177 0);
184} 178}
185 179
186/* 180static int mt9p031_pll_setup(struct mt9p031 *mt9p031)
187 * This static table uses ext_freq and vdd_io values to select suitable
188 * PLL dividers m, n and p1 which have been calculated as specifiec in p36
189 * of Aptina's mt9p031 datasheet. New values should be added here.
190 */
191static const struct mt9p031_pll_divs mt9p031_divs[] = {
192 /* ext_freq target_freq m n p1 */
193 {21000000, 48000000, 26, 2, 6}
194};
195
196static int mt9p031_pll_get_divs(struct mt9p031 *mt9p031)
197{ 181{
182 static const struct aptina_pll_limits limits = {
183 .ext_clock_min = 6000000,
184 .ext_clock_max = 27000000,
185 .int_clock_min = 2000000,
186 .int_clock_max = 13500000,
187 .out_clock_min = 180000000,
188 .out_clock_max = 360000000,
189 .pix_clock_max = 96000000,
190 .n_min = 1,
191 .n_max = 64,
192 .m_min = 16,
193 .m_max = 255,
194 .p1_min = 1,
195 .p1_max = 128,
196 };
197
198 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev); 198 struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev);
199 int i; 199 struct mt9p031_platform_data *pdata = mt9p031->pdata;
200 200
201 for (i = 0; i < ARRAY_SIZE(mt9p031_divs); i++) { 201 mt9p031->pll.ext_clock = pdata->ext_freq;
202 if (mt9p031_divs[i].ext_freq == mt9p031->pdata->ext_freq && 202 mt9p031->pll.pix_clock = pdata->target_freq;
203 mt9p031_divs[i].target_freq == mt9p031->pdata->target_freq) {
204 mt9p031->pll = &mt9p031_divs[i];
205 return 0;
206 }
207 }
208 203
209 dev_err(&client->dev, "Couldn't find PLL dividers for ext_freq = %d, " 204 return aptina_pll_calculate(&client->dev, &limits, &mt9p031->pll);
210 "target_freq = %d\n", mt9p031->pdata->ext_freq,
211 mt9p031->pdata->target_freq);
212 return -EINVAL;
213} 205}
214 206
215static int mt9p031_pll_enable(struct mt9p031 *mt9p031) 207static int mt9p031_pll_enable(struct mt9p031 *mt9p031)
@@ -223,11 +215,11 @@ static int mt9p031_pll_enable(struct mt9p031 *mt9p031)
223 return ret; 215 return ret;
224 216
225 ret = mt9p031_write(client, MT9P031_PLL_CONFIG_1, 217 ret = mt9p031_write(client, MT9P031_PLL_CONFIG_1,
226 (mt9p031->pll->m << 8) | (mt9p031->pll->n - 1)); 218 (mt9p031->pll.m << 8) | (mt9p031->pll.n - 1));
227 if (ret < 0) 219 if (ret < 0)
228 return ret; 220 return ret;
229 221
230 ret = mt9p031_write(client, MT9P031_PLL_CONFIG_2, mt9p031->pll->p1 - 1); 222 ret = mt9p031_write(client, MT9P031_PLL_CONFIG_2, mt9p031->pll.p1 - 1);
231 if (ret < 0) 223 if (ret < 0)
232 return ret; 224 return ret;
233 225
@@ -900,7 +892,7 @@ static int mt9p031_probe(struct i2c_client *client,
900 mt9p031->format.field = V4L2_FIELD_NONE; 892 mt9p031->format.field = V4L2_FIELD_NONE;
901 mt9p031->format.colorspace = V4L2_COLORSPACE_SRGB; 893 mt9p031->format.colorspace = V4L2_COLORSPACE_SRGB;
902 894
903 ret = mt9p031_pll_get_divs(mt9p031); 895 ret = mt9p031_pll_setup(mt9p031);
904 896
905done: 897done:
906 if (ret < 0) { 898 if (ret < 0) {