aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/s5p-tv/hdmiphy_drv.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/platform/s5p-tv/hdmiphy_drv.c')
-rw-r--r--drivers/media/platform/s5p-tv/hdmiphy_drv.c55
1 files changed, 22 insertions, 33 deletions
diff --git a/drivers/media/platform/s5p-tv/hdmiphy_drv.c b/drivers/media/platform/s5p-tv/hdmiphy_drv.c
index 80717cec76ae..e19a0af1ea4f 100644
--- a/drivers/media/platform/s5p-tv/hdmiphy_drv.c
+++ b/drivers/media/platform/s5p-tv/hdmiphy_drv.c
@@ -176,35 +176,9 @@ static inline struct hdmiphy_ctx *sd_to_ctx(struct v4l2_subdev *sd)
176 return container_of(sd, struct hdmiphy_ctx, sd); 176 return container_of(sd, struct hdmiphy_ctx, sd);
177} 177}
178 178
179static unsigned long hdmiphy_preset_to_pixclk(u32 preset) 179static const u8 *hdmiphy_find_conf(unsigned long pixclk,
180 const struct hdmiphy_conf *conf)
180{ 181{
181 static const unsigned long pixclk[] = {
182 [V4L2_DV_480P59_94] = 27000000,
183 [V4L2_DV_576P50] = 27000000,
184 [V4L2_DV_720P59_94] = 74176000,
185 [V4L2_DV_720P50] = 74250000,
186 [V4L2_DV_720P60] = 74250000,
187 [V4L2_DV_1080P24] = 74250000,
188 [V4L2_DV_1080P30] = 74250000,
189 [V4L2_DV_1080I50] = 74250000,
190 [V4L2_DV_1080I60] = 74250000,
191 [V4L2_DV_1080P50] = 148500000,
192 [V4L2_DV_1080P60] = 148500000,
193 };
194 if (preset < ARRAY_SIZE(pixclk))
195 return pixclk[preset];
196 else
197 return 0;
198}
199
200static const u8 *hdmiphy_find_conf(u32 preset, const struct hdmiphy_conf *conf)
201{
202 unsigned long pixclk;
203
204 pixclk = hdmiphy_preset_to_pixclk(preset);
205 if (!pixclk)
206 return NULL;
207
208 for (; conf->pixclk; ++conf) 182 for (; conf->pixclk; ++conf)
209 if (conf->pixclk == pixclk) 183 if (conf->pixclk == pixclk)
210 return conf->data; 184 return conf->data;
@@ -217,8 +191,8 @@ static int hdmiphy_s_power(struct v4l2_subdev *sd, int on)
217 return 0; 191 return 0;
218} 192}
219 193
220static int hdmiphy_s_dv_preset(struct v4l2_subdev *sd, 194static int hdmiphy_s_dv_timings(struct v4l2_subdev *sd,
221 struct v4l2_dv_preset *preset) 195 struct v4l2_dv_timings *timings)
222{ 196{
223 const u8 *data; 197 const u8 *data;
224 u8 buffer[32]; 198 u8 buffer[32];
@@ -226,9 +200,12 @@ static int hdmiphy_s_dv_preset(struct v4l2_subdev *sd,
226 struct hdmiphy_ctx *ctx = sd_to_ctx(sd); 200 struct hdmiphy_ctx *ctx = sd_to_ctx(sd);
227 struct i2c_client *client = v4l2_get_subdevdata(sd); 201 struct i2c_client *client = v4l2_get_subdevdata(sd);
228 struct device *dev = &client->dev; 202 struct device *dev = &client->dev;
203 unsigned long pixclk = timings->bt.pixelclock;
229 204
230 dev_info(dev, "s_dv_preset(preset = %d)\n", preset->preset); 205 dev_info(dev, "s_dv_timings\n");
231 data = hdmiphy_find_conf(preset->preset, ctx->conf_tab); 206 if ((timings->bt.flags & V4L2_DV_FL_REDUCED_FPS) && pixclk == 74250000)
207 pixclk = 74176000;
208 data = hdmiphy_find_conf(pixclk, ctx->conf_tab);
232 if (!data) { 209 if (!data) {
233 dev_err(dev, "format not supported\n"); 210 dev_err(dev, "format not supported\n");
234 return -EINVAL; 211 return -EINVAL;
@@ -245,6 +222,17 @@ static int hdmiphy_s_dv_preset(struct v4l2_subdev *sd,
245 return 0; 222 return 0;
246} 223}
247 224
225static int hdmiphy_dv_timings_cap(struct v4l2_subdev *sd,
226 struct v4l2_dv_timings_cap *cap)
227{
228 cap->type = V4L2_DV_BT_656_1120;
229 /* The phy only determines the pixelclock, leave the other values
230 * at 0 to signify that we have no information for them. */
231 cap->bt.min_pixelclock = 27000000;
232 cap->bt.max_pixelclock = 148500000;
233 return 0;
234}
235
248static int hdmiphy_s_stream(struct v4l2_subdev *sd, int enable) 236static int hdmiphy_s_stream(struct v4l2_subdev *sd, int enable)
249{ 237{
250 struct i2c_client *client = v4l2_get_subdevdata(sd); 238 struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -270,7 +258,8 @@ static const struct v4l2_subdev_core_ops hdmiphy_core_ops = {
270}; 258};
271 259
272static const struct v4l2_subdev_video_ops hdmiphy_video_ops = { 260static const struct v4l2_subdev_video_ops hdmiphy_video_ops = {
273 .s_dv_preset = hdmiphy_s_dv_preset, 261 .s_dv_timings = hdmiphy_s_dv_timings,
262 .dv_timings_cap = hdmiphy_dv_timings_cap,
274 .s_stream = hdmiphy_s_stream, 263 .s_stream = hdmiphy_s_stream,
275}; 264};
276 265