1 #include <linux/kernel.h>
\r
2 #include <linux/delay.h>
\r
3 #include <linux/module.h>
\r
4 #include <linux/platform_device.h>
\r
5 #include <linux/hdmi.h>
\r
6 #include <linux/i2c.h>
\r
7 #include <linux/interrupt.h>
\r
8 #include <mach/gpio.h>
\r
9 #include <mach/iomux.h>
\r
10 #include <mach/board.h>
\r
11 #include <linux/irq.h>
\r
13 #include <linux/mfd/rk610_core.h>
\r
14 #include "rk610_hdmi.h"
\r
15 #include "rk610_hdmi_hw.h"
\r
18 struct i2c_client *rk610_g_hdmi_client=NULL;
\r
21 static void rk610_handler(struct work_struct *work)
\r
23 struct i2c_client *client = rk610_g_hdmi_client;
\r
25 printk(">>> %s client==NULL\n",__func__);
\r
27 Rk610_hdmi_event_work(client,&hpd);
\r
30 static DECLARE_DELAYED_WORK(rk610_irq_work, rk610_handler);
\r
31 static int rk610_hdmi_precent(struct hdmi *hdmi)
\r
33 //struct rk610_hdmi_inf *rk610_hdmi = hdmi_priv(hdmi);
\r
34 schedule_delayed_work(&rk610_irq_work, msecs_to_jiffies(30));
\r
38 static int rk610_hdmi_param_chg(struct rk610_hdmi_inf *rk610_hdmi)
\r
40 int resolution_real;
\r
41 RK610_DBG(&rk610_hdmi->client->dev,"%s \n",__FUNCTION__);
\r
42 resolution_real = Rk610_Get_Optimal_resolution(rk610_hdmi->hdmi->resolution);
\r
43 rk610_hdmi->hdmi->resolution = resolution_real;
\r
44 hdmi_switch_fb(rk610_hdmi->hdmi, rk610_hdmi->hdmi->display_on);
\r
45 Rk610_hdmi_Set_Video(rk610_hdmi->hdmi->resolution);
\r
46 Rk610_hdmi_Set_Audio(rk610_hdmi->hdmi->audio_fs);
\r
47 Rk610_hdmi_Config_Done(rk610_hdmi->client);
\r
51 static int rk610_hdmi_set_param(struct hdmi *hdmi)
\r
53 struct rk610_hdmi_inf *rk610_hdmi = hdmi_priv(hdmi);
\r
54 RK610_DBG(&rk610_hdmi->client->dev,"%s \n",__FUNCTION__);
\r
55 if(rk610_hdmi->init == 1)
\r
58 rk610_hdmi_param_chg(rk610_hdmi);
\r
61 static int rk610_hdmi_insert(struct hdmi *hdmi)
\r
63 struct rk610_hdmi_inf *rk610_hdmi = hdmi_priv(hdmi);
\r
64 RK610_DBG(&rk610_hdmi->client->dev,"%s \n",__FUNCTION__);
\r
65 if(rk610_hdmi->init == 1)
\r
67 rk610_hdmi_param_chg(rk610_hdmi);
\r
68 hdmi_set_spk(HDMI_DISABLE);
\r
69 printk("rk610_hdmi_insert hdmi->display_on=%d\n",hdmi->display_on);
\r
70 hdmi->scale = hdmi->scale_set;
\r
73 static int rk610_hdmi_remove(struct hdmi *hdmi)
\r
75 struct rk610_hdmi_inf *rk610_hdmi = hdmi_priv(hdmi);
\r
76 RK610_DBG(&rk610_hdmi->client->dev,"%s \n",__FUNCTION__);
\r
77 if(rk610_hdmi->init == 1)
\r
79 hdmi_set_spk(HDMI_ENABLE);
\r
80 hdmi_switch_fb(hdmi, HDMI_DISABLE);
\r
81 printk("rk610_hdmi_remove hdmi->display_on=%d\n",hdmi->display_on);
\r
84 #ifdef CONFIG_HAS_EARLYSUSPEND
\r
85 static void rk610_hdmi_early_suspend(struct early_suspend *h)
\r
87 struct rk610_hdmi_inf *rk610_hdmi = container_of(h,
\r
88 struct rk610_hdmi_inf,
\r
90 printk( "rk610_hdmi enter early suspend\n");
\r
91 hdmi_suspend(rk610_hdmi->hdmi);
\r
92 Rk610_hdmi_suspend(rk610_hdmi->client);
\r
96 static void rk610_hdmi_early_resume(struct early_suspend *h)
\r
98 struct rk610_hdmi_inf *rk610_hdmi = container_of(h,
\r
99 struct rk610_hdmi_inf,
\r
101 printk("rk610_hdmi exit early suspend\n");
\r
102 hdmi_resume(rk610_hdmi->hdmi);
\r
103 Rk610_hdmi_resume(rk610_hdmi->client);
\r
108 static int rk610_hdmi_init(struct hdmi *hdmi)
\r
110 struct rk610_hdmi_inf *rk610_hdmi = hdmi_priv(hdmi);
\r
111 #ifdef CONFIG_HDMI_SAVE_DATA
\r
112 int hdmi_data = hdmi_get_data();
\r
114 hdmi_set_data((hdmi->resolution&0x7)|((hdmi->scale&0x1f)<<3));
\r
117 hdmi->resolution = hdmi_data&0x7;
\r
118 hdmi->scale_set= ((hdmi_data>>3)&0x1f) + MIN_SCALE;
\r
119 hdmi->scale = hdmi->scale_set;
\r
122 RK610_DBG(&rk610_hdmi->client->dev,"%s \n",__FUNCTION__);
\r
123 rk610_hdmi->init =0;
\r
124 Rk610_hdmi_init(rk610_hdmi->client);
\r
125 hdmi_changed(hdmi,1);
\r
126 Rk610_hdmi_Set_Video(hdmi->resolution);
\r
127 Rk610_hdmi_Set_Audio(hdmi->audio_fs);
\r
128 Rk610_hdmi_Config_Done(rk610_hdmi->client);
\r
131 static struct hdmi_ops rk610_hdmi_ops = {
\r
132 .set_param = rk610_hdmi_set_param,
\r
133 .hdmi_precent = rk610_hdmi_precent,
\r
134 .insert = rk610_hdmi_insert,
\r
135 .remove = rk610_hdmi_remove,
\r
136 .init = rk610_hdmi_init,
\r
139 static int rk610_read_p0_reg(struct i2c_client *client, char reg, char *val)
141 return i2c_master_reg8_recv(client, reg, val, 1, 100*1000) > 0? 0: -EINVAL;
144 static int rk610_write_p0_reg(struct i2c_client *client, char reg, char *val)
146 return i2c_master_reg8_send(client, reg, val, 1, 100*1000) > 0? 0: -EINVAL;
148 static ssize_t rk610_show_reg_attrs(struct device *dev,
149 struct device_attribute *attr,
155 struct i2c_client *client=rk610_g_hdmi_client;
\r
159 rk610_read_p0_reg(client, i, &val);
161 size += sprintf(buf+size,"\n>>>rk610_hdmi %x:",i);
162 size += sprintf(buf+size," %2x",val);
167 static ssize_t rk610_store_reg_attrs(struct device *dev,
168 struct device_attribute *attr,
169 const char *buf, size_t size)
171 struct i2c_client *client=NULL;
172 static char val=0,reg=0;
173 client = rk610_g_hdmi_client;
\r
174 RK610_DBG(&client->dev,"/**********rk610 reg config******/");
\r
176 sscanf(buf, "%x%x", &val,®);
177 RK610_DBG(&client->dev,"reg=%x val=%x\n",reg,val);
\r
178 rk610_write_p0_reg(client, reg, &val);
179 RK610_DBG(&client->dev,"val=%x\n",val);
\r
183 static struct device_attribute rk610_attrs[] = {
184 __ATTR(reg_ctl, 0777,rk610_show_reg_attrs,rk610_store_reg_attrs),
188 static irqreturn_t rk610_hdmi_interrupt(int irq, void *dev_id)
\r
190 struct hdmi *hdmi = (struct hdmi *)dev_id;
\r
191 unsigned long lock_flags = 0;
\r
192 printk("The rk610_hdmi interrupt handeler is working..\n");
\r
193 return IRQ_HANDLED;
\r
197 static int rk610_hdmi_i2c_probe(struct i2c_client *client,const struct i2c_device_id *id)
\r
200 struct hdmi *hdmi = NULL;
\r
201 struct rk610_hdmi_inf *rk610_hdmi = NULL;
\r
203 struct hdmi_platform_data *pdata = client->dev.platform_data;
\r
204 rk610_g_hdmi_client = client;
\r
205 if(pdata && pdata->io_init)
\r
207 printk("rk610_hdmi_i2c_probe io_init \n");
\r
210 hdmi = hdmi_register(sizeof(struct rk610_hdmi_inf), &client->dev);
\r
213 dev_err(&client->dev, "fail to register hdmi\n");
\r
216 hdmi->ops = &rk610_hdmi_ops;
\r
217 hdmi->display_on = HDMI_DEFAULT_MODE;
\r
218 hdmi->hdcp_on = HDMI_DISABLE;
\r
219 hdmi->audio_fs = HDMI_I2S_DEFAULT_Fs;
\r
220 hdmi->resolution = HDMI_DEFAULT_RESOLUTION;
\r
221 hdmi->dual_disp = DUAL_DISP_CAP;
\r
222 hdmi->mode = DISP_ON_LCD;
\r
224 hdmi->scale_set = 100;
\r
226 rk610_hdmi = hdmi_priv(hdmi);
\r
227 rk610_hdmi->init = 1;
\r
228 rk610_hdmi->hdmi = hdmi;
\r
229 i2c_set_clientdata(client, rk610_hdmi);
\r
230 rk610_hdmi->client = client;
\r
231 if((gpio_request(client->irq, "hdmi gpio")) < 0)
\r
233 dev_err(&client->dev, "fail to request gpio %d\n", client->irq);
\r
234 goto err_gpio_free;
\r
236 rk610_hdmi->irq = gpio_to_irq(client->irq);
\r
237 rk610_hdmi->gpio = client->irq;
\r
239 gpio_direction_input(client->irq);
\r
241 if((ret = request_irq(rk610_hdmi->irq, rk610_hdmi_interrupt, IRQ_TYPE_EDGE_RISING,client->name, hdmi))<0){
\r
242 RK610_ERR(&client->dev, "fail to request gpio %d\n", client->irq);
\r
243 goto err_gpio_free;
\r
246 #ifdef CONFIG_HAS_EARLYSUSPEND
\r
247 rk610_hdmi->early_suspend.suspend = rk610_hdmi_early_suspend;
\r
248 rk610_hdmi->early_suspend.resume = rk610_hdmi_early_resume;
\r
249 rk610_hdmi->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN - 1;
\r
250 register_early_suspend(&rk610_hdmi->early_suspend);
\r
253 device_create_file(&(client->dev), &rk610_attrs[0]);
\r
255 rk610_hdmi_init(rk610_hdmi->hdmi);
\r
256 dev_info(&client->dev, "rk610_hdmi i2c probe ok\n");
\r
259 gpio_free(client->irq);
\r
260 err_hdmi_unregister:
\r
261 hdmi_unregister(hdmi);
\r
266 static int __devexit rk610_hdmi_i2c_remove(struct i2c_client *client)
\r
268 struct rk610_hdmi_inf *rk610_hdmi = (struct rk610_hdmi_inf *)i2c_get_clientdata(client);
\r
269 struct hdmi *hdmi = rk610_hdmi->hdmi;
\r
271 gpio_free(client->irq);
\r
272 hdmi_unregister(hdmi);
\r
276 static const struct i2c_device_id rk610_hdmi_id[] = {
\r
277 { "rk610_hdmi", 0 },
\r
281 static struct i2c_driver rk610_hdmi_i2c_driver = {
\r
283 .name = "rk610_hdmi",
\r
285 .probe = &rk610_hdmi_i2c_probe,
\r
286 .remove = &rk610_hdmi_i2c_remove,
\r
287 .id_table = rk610_hdmi_id,
\r
290 static int __init rk610_hdmi_module_init(void)
\r
292 return i2c_add_driver(&rk610_hdmi_i2c_driver);
\r
295 static void __exit rk610_hdmi_module_exit(void)
\r
297 i2c_del_driver(&rk610_hdmi_i2c_driver);
\r
300 module_init(rk610_hdmi_module_init);
\r
301 //module_init(rk610_hdmi_module_init);
\r
302 module_exit(rk610_hdmi_module_exit);
\r