From 7fa437462cebdc34dd51162873e20b8e69203a82 Mon Sep 17 00:00:00 2001 From: xingbin Date: Thu, 10 Jan 2019 15:05:41 +0800 Subject: [PATCH] (CR):[Kane]:[factory]modify the HBM operaton on suspend mode Bug:(CR) Change-Id: I286d860ea1cc539ae308783eb9253dac5095f249 Signed-off-by: xingbin --- drivers/video/backlight/lm36923.c | 164 +++++++++++++++++++++++---- drivers/video/backlight/lm36923.h | 4 + drivers/video/backlight/sgm37603a.c | 170 ++++++++++++++++++++++++---- drivers/video/backlight/sgm37603a.h | 4 + 4 files changed, 293 insertions(+), 49 deletions(-) diff --git a/drivers/video/backlight/lm36923.c b/drivers/video/backlight/lm36923.c index 0774708c1151..2395472e1b1c 100755 --- a/drivers/video/backlight/lm36923.c +++ b/drivers/video/backlight/lm36923.c @@ -18,6 +18,9 @@ #include #include #include +#ifdef CONFIG_FB +#include +#endif #ifdef CONFIG_OF #include #endif @@ -85,10 +88,21 @@ static ssize_t lm36923_mode_store(struct device *dev, struct device_attribute *a return ret; } + i2c_data->mode = value; + + if(i2c_data->is_suspend){ + pr_err("device is suspend now, set HBM mode on next power on\n"); + goto exit; + } + pr_err("%s: current mode=%d, now write to %d\n", __func__, i2c_data->mode, value); if(1 == value){ - mutex_lock(&i2c_data->lock); + if(mutex_trylock(&i2c_data->lock)==0){ + pr_err("%s: lm36923 dev is busy\n",__func__); + goto exit; + } + ret = backlight_i2c_write_bits(i2c_data,lm_hl_data[0][0],LM_LSB_MASK,lm_hl_data[0][1]); //write LSB if(ret < 0){ pr_err("HL mode:write lm chip LSB bit error\n"); @@ -102,11 +116,14 @@ static ssize_t lm36923_mode_store(struct device *dev, struct device_attribute *a mutex_unlock(&i2c_data->lock); goto exit; } - i2c_data->mode = value; mutex_unlock(&i2c_data->lock); } else if(0 == value){ - mutex_lock(&i2c_data->lock); + if(mutex_trylock(&i2c_data->lock)==0){ + pr_err("%s: lm36923 dev is busy\n",__func__); + goto exit; + } + ret = backlight_i2c_write_bits(i2c_data,lm_nr_data[0][0],LM_LSB_MASK,lm_nr_data[0][1]); //write LSB if(ret < 0){ pr_err("NR mode:write lm chip LSB bit error\n"); @@ -120,7 +137,6 @@ static ssize_t lm36923_mode_store(struct device *dev, struct device_attribute *a mutex_unlock(&i2c_data->lock); goto exit; } - i2c_data->mode = value; mutex_unlock(&i2c_data->lock); } else{ @@ -231,12 +247,101 @@ static int getChipId(struct device *dev){ return (value&BACKLIGHT_CHIP_ID_REG_MASK)>>4; } - +#if defined(CONFIG_FB) +static int lm36923_resume(struct lm36923_data *dev_data) +{ + int ret = 0; + dev_data->is_suspend = 0; + if (!dev_data) { + pr_err("%s: kzalloc error\n",__func__); + return -ENOMEM; + } + pr_info("%s:now write mode to %d\n",__func__,dev_data->mode); + if(1 == dev_data->mode){ + if(mutex_trylock(&dev_data->lock)==0){ + pr_err("%s: lm36923 dev is busy\n",__func__); + goto exit; + } + + ret = backlight_i2c_write_bits(dev_data,lm_hl_data[0][0],LM_LSB_MASK,lm_hl_data[0][1]); //write LSB + if(ret < 0){ + pr_err("HL mode:write sgm chip LSB bit error\n"); + mutex_unlock(&dev_data->lock); + goto exit; + } + + ret = backlight_i2c_write(dev_data,lm_hl_data[1][0],lm_hl_data[1][1]); //write MSB + if(ret < 0){ + pr_err("HL mode:write sgm chip MSB error\n"); + mutex_unlock(&dev_data->lock); + goto exit; + } + mutex_unlock(&dev_data->lock); + }else if(0 == dev_data->mode){ + if(mutex_trylock(&dev_data->lock)==0){ + pr_err("%s: lm36923 dev is busy\n",__func__); + goto exit; + } + + ret = backlight_i2c_write_bits(dev_data,lm_nr_data[0][0],LM_LSB_MASK,lm_nr_data[0][1]); //write LSB + if(ret < 0){ + pr_err("NR mode:write sgm chip LSB bit error\n"); + mutex_unlock(&dev_data->lock); + goto exit; + } + + ret = backlight_i2c_write(dev_data,lm_nr_data[1][0],lm_nr_data[1][1]); //write MSB + if(ret < 0){ + pr_err("NR mode:write sgm chip MSB error\n"); + mutex_unlock(&dev_data->lock); + goto exit; + } + mutex_unlock(&dev_data->lock); + } + else{ + pr_err("the error echo value, 0 or 1 is allowed only\n"); + } +exit: + return ret; +} +static int lm36923_suspend(struct lm36923_data *dev_data) +{ + int ret = 0; + dev_data->is_suspend = 1; + return ret; +} +static int fb_notifier_callback(struct notifier_block *self, + unsigned long event, void *data) +{ + int *blank; + struct fb_event *evdata = data; + struct lm36923_data *lm = + container_of(self, struct lm36923_data, fb_notif); + + if (evdata && evdata->data && event == FB_EVENT_BLANK ) { + blank = evdata->data; + switch (*blank) { + case FB_BLANK_UNBLANK: + lm36923_resume(lm); + break; + case FB_BLANK_POWERDOWN: + case FB_BLANK_HSYNC_SUSPEND: + case FB_BLANK_VSYNC_SUSPEND: + case FB_BLANK_NORMAL: + lm36923_suspend(lm); + break; + default: + break; + } + } + return 0; +} +#endif static int lm36923_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret = 0; - struct lm36923_data *data; + struct lm36923_data *lm; struct device_node *np=client->dev.of_node; pr_err("%s: enter\n",__func__); @@ -245,21 +350,22 @@ static int lm36923_probe(struct i2c_client *client, return -EIO; } - data = devm_kzalloc(&client->dev,sizeof(struct lm36923_data), GFP_KERNEL); - if (!data) { + lm = devm_kzalloc(&client->dev,sizeof(struct lm36923_data), GFP_KERNEL); + if (!lm) { pr_err("%s: kzalloc error\n",__func__); return -ENOMEM; } - data->bk_i2c_client = client; - mutex_init(&data->lock); - data->mode = 0; + lm->bk_i2c_client = client; + mutex_init(&lm->lock); + lm->mode = 0; + lm->is_suspend = 0; - i2c_set_clientdata(client, data); - lmdata=data; + i2c_set_clientdata(client, lm); + lmdata=lm; if (np) { - ret = lm36923_parse_dt(&client->dev, data, np); + ret = lm36923_parse_dt(&client->dev, lm, np); if (ret) { dev_err(&client->dev,"Unable to parse platfrom data err=%d\n", ret); goto kfree_exit; @@ -276,18 +382,18 @@ static int lm36923_probe(struct i2c_client *client, if(0==chipid){ printk(KERN_ERR "lm36923 chip\n"); - mutex_lock(&data->lock); - data->name="lm36923\0"; - ret = backlight_i2c_write_bits(data,lm_nr_data[0][0],LM_LSB_MASK,lm_nr_data[0][1]); + mutex_lock(&lm->lock); + lm->name="lm36923\0"; + ret = backlight_i2c_write_bits(lm,lm_nr_data[0][0],LM_LSB_MASK,lm_nr_data[0][1]); if(ret < 0){ pr_err("%s:NR mode:write lm chip LSB bit error\n",__func__); } - ret = backlight_i2c_write(data,lm_nr_data[1][0],lm_nr_data[1][1]); //write MSB + ret = backlight_i2c_write(lm,lm_nr_data[1][0],lm_nr_data[1][1]); //write MSB if(ret < 0){ pr_err("%s:NR mode:write lm chip MSB error\n",__func__); } - mutex_unlock(&data->lock); + mutex_unlock(&lm->lock); } else{ dev_err(&client->dev,"wrong chipid\n"); @@ -307,22 +413,32 @@ static int lm36923_probe(struct i2c_client *client, dev_err(&bd->dev,"Unable to create backlight_i2c_attribute\n"); goto kfree_sysfs; } +#if defined(CONFIG_FB) + lm->fb_notif.notifier_call = fb_notifier_callback; + ret = fb_register_client(&lm->fb_notif); + if (ret) { + pr_err("Unable to register fb_notifier: %d\n", ret); + goto err_register_fb_notif_failed; + } +#endif return 0; - +#if defined(CONFIG_FB) +err_register_fb_notif_failed: +#endif kfree_sysfs: sysfs_remove_group(&bd->dev.kobj, &lm36923_attribute_group); kfree_node: backlight_device_unregister(bd); kfree_exit: - mutex_destroy(&data->lock); + mutex_destroy(&lm->lock); return ret; } static int lm36923_remove(struct i2c_client *client) { - struct lm36923_data *data = lmdata; + struct lm36923_data *lm = lmdata; if(lmdata != NULL) - mutex_destroy(&data->lock); + mutex_destroy(&lm->lock); sysfs_remove_group(&bd->dev.kobj, &lm36923_attribute_group); backlight_device_unregister(bd); return 0; @@ -376,4 +492,4 @@ MODULE_DESCRIPTION("LCD_BACKLIGHT davicom ic driver"); MODULE_LICENSE("GPL"); module_init(lm36923_init); -module_exit(lm36923_exit); \ No newline at end of file +module_exit(lm36923_exit); diff --git a/drivers/video/backlight/lm36923.h b/drivers/video/backlight/lm36923.h index 1f0905c7c8ee..55f24cc334a0 100755 --- a/drivers/video/backlight/lm36923.h +++ b/drivers/video/backlight/lm36923.h @@ -49,6 +49,10 @@ struct lm36923_data { struct mutex lock; unsigned char mode; char* name; +#if defined(CONFIG_FB) + struct notifier_block fb_notif; +#endif + unsigned char is_suspend; }; //lm 36923 diff --git a/drivers/video/backlight/sgm37603a.c b/drivers/video/backlight/sgm37603a.c index 36d1d53b46f6..063b6578c085 100755 --- a/drivers/video/backlight/sgm37603a.c +++ b/drivers/video/backlight/sgm37603a.c @@ -18,6 +18,9 @@ #include #include #include +#if defined(CONFIG_FB) +#include +#endif #ifdef CONFIG_OF #include #endif @@ -86,10 +89,21 @@ static ssize_t sgm37603a_mode_store(struct device *dev, struct device_attribute return ret; } + i2c_data->mode = value; + + if(i2c_data->is_suspend){ + pr_err("device is suspend now, set HBM mode on next power on\n"); + goto exit; + } + pr_err("%s: current mode=%d, now write to %d\n", __func__, i2c_data->mode, value); if(1 == value){ - mutex_lock(&i2c_data->lock); + if(mutex_trylock(&i2c_data->lock)==0){ + pr_err("%s: sgm37603a dev is busy\n",__func__); + goto exit; + } + ret = backlight_i2c_write_bits(i2c_data,sgm_hl_data[0][0],SGM_LSB_MASK,sgm_hl_data[0][1]); //write LSB if(ret < 0){ pr_err("HL mode:write sgm chip LSB bit error\n"); @@ -103,11 +117,14 @@ static ssize_t sgm37603a_mode_store(struct device *dev, struct device_attribute mutex_unlock(&i2c_data->lock); goto exit; } - i2c_data->mode = value; mutex_unlock(&i2c_data->lock); } else if(0 == value){ - mutex_lock(&i2c_data->lock); + if(mutex_trylock(&i2c_data->lock)==0){ + pr_err("%s: sgm37603a dev is busy\n",__func__); + goto exit; + } + ret = backlight_i2c_write_bits(i2c_data,sgm_nr_data[0][0],SGM_LSB_MASK,sgm_nr_data[0][1]); //write LSB if(ret < 0){ pr_err("NR mode:write sgm chip LSB bit error\n"); @@ -121,7 +138,6 @@ static ssize_t sgm37603a_mode_store(struct device *dev, struct device_attribute mutex_unlock(&i2c_data->lock); goto exit; } - i2c_data->mode = value; mutex_unlock(&i2c_data->lock); } else{ @@ -158,8 +174,8 @@ static ssize_t sgm37603a_chip_reg_store(struct device *dev, int ret = -1; unsigned char reg; unsigned char val; - struct sgm37603a_data *i2c_data = sgmdata; - + struct sgm37603a_data *i2c_data = sgmdata; + if(!count || i2c_data==NULL){ pr_err("%s:count=0 or i2c_data is NULL pointer\n",__func__); return -EINVAL; @@ -233,12 +249,104 @@ static int getChipId(struct device *dev){ return (value&BACKLIGHT_CHIP_ID_REG_MASK)>>4; } +#if defined(CONFIG_FB) +static int sgm37603a_resume(struct sgm37603a_data *dev_data) +{ + int ret = 0; + + dev_data->is_suspend = 0; + if (!dev_data) { + pr_err("%s: kzalloc error\n",__func__); + return -ENOMEM; + } + pr_info("%s:now write mode to %d\n",__func__,dev_data->mode); + if(1 == dev_data->mode){ + if(mutex_trylock(&dev_data->lock)==0){ + pr_err("%s: sgm37603a dev is busy\n",__func__); + goto exit; + } + + ret = backlight_i2c_write_bits(dev_data,sgm_hl_data[0][0],SGM_LSB_MASK,sgm_hl_data[0][1]); //write LSB + if(ret < 0){ + pr_err("HL mode:write sgm chip LSB bit error\n"); + mutex_unlock(&dev_data->lock); + goto exit; + } + + ret = backlight_i2c_write(dev_data,sgm_hl_data[1][0],sgm_hl_data[1][1]); //write MSB + if(ret < 0){ + pr_err("HL mode:write sgm chip MSB error\n"); + mutex_unlock(&dev_data->lock); + goto exit; + } + mutex_unlock(&dev_data->lock); + }else if(0 == dev_data->mode){ + if(mutex_trylock(&dev_data->lock)==0){ + pr_err("%s: sgm37603a dev is busy\n",__func__); + goto exit; + } + + ret = backlight_i2c_write_bits(dev_data,sgm_nr_data[0][0],SGM_LSB_MASK,sgm_nr_data[0][1]); //write LSB + if(ret < 0){ + pr_err("NR mode:write sgm chip LSB bit error\n"); + mutex_unlock(&dev_data->lock); + goto exit; + } + + ret = backlight_i2c_write(dev_data,sgm_nr_data[1][0],sgm_nr_data[1][1]); //write MSB + if(ret < 0){ + pr_err("NR mode:write sgm chip MSB error\n"); + mutex_unlock(&dev_data->lock); + goto exit; + } + mutex_unlock(&dev_data->lock); + } + else{ + pr_err("the error echo value, 0 or 1 is allowed only\n"); + } +exit: + return ret; +} +static int sgm37603a_suspend(struct sgm37603a_data *dev_data) +{ + int ret = 0; + dev_data->is_suspend = 1; + return ret; +} + +static int fb_notifier_callback(struct notifier_block *self, + unsigned long event, void *data) +{ + int *blank; + struct fb_event *evdata = data; + struct sgm37603a_data *sgm = + container_of(self, struct sgm37603a_data, fb_notif); + + if (evdata && evdata->data && event == FB_EVENT_BLANK ) { + blank = evdata->data; + switch (*blank) { + case FB_BLANK_UNBLANK: + sgm37603a_resume(sgm); + break; + case FB_BLANK_POWERDOWN: + case FB_BLANK_HSYNC_SUSPEND: + case FB_BLANK_VSYNC_SUSPEND: + case FB_BLANK_NORMAL: + sgm37603a_suspend(sgm); + break; + default: + break; + } + } + return 0; +} +#endif static int sgm37603a_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret = 0; - struct sgm37603a_data *data; + struct sgm37603a_data *sgm; struct device_node *np=client->dev.of_node; pr_err("%s: enter\n",__func__); @@ -248,20 +356,21 @@ static int sgm37603a_probe(struct i2c_client *client, return -EIO; } - data = devm_kzalloc(&client->dev,sizeof(struct sgm37603a_data), GFP_KERNEL); - if (!data) { + sgm = devm_kzalloc(&client->dev,sizeof(struct sgm37603a_data), GFP_KERNEL); + if (!sgm) { pr_err("%s: kzalloc error\n",__func__); return -ENOMEM; } - data->bk_i2c_client = client; - mutex_init(&data->lock); - data->mode = 0; - i2c_set_clientdata(client, data); - sgmdata=data; + sgm->bk_i2c_client = client; + mutex_init(&sgm->lock); + sgm->mode = 0; + sgm->is_suspend = 0; + i2c_set_clientdata(client, sgm); + sgmdata=sgm; if (np) { - ret = sgm37603a_parse_dt(&client->dev, data, np); + ret = sgm37603a_parse_dt(&client->dev, sgm, np); if (ret) { dev_err(&client->dev,"Unable to parse platfrom data err=%d\n", ret); goto kfree_exit; @@ -277,18 +386,18 @@ static int sgm37603a_probe(struct i2c_client *client, if(1==chipid){ printk(KERN_ERR "sgm37603 chip\n"); - mutex_lock(&data->lock); - data->name="sgm37603\0"; - ret = backlight_i2c_write_bits(data,sgm_nr_data[0][0],SGM_LSB_MASK,sgm_nr_data[0][1]); + mutex_lock(&sgm->lock); + sgm->name="sgm37603\0"; + ret = backlight_i2c_write_bits(sgm,sgm_nr_data[0][0],SGM_LSB_MASK,sgm_nr_data[0][1]); if(ret < 0){ pr_err("%s:NR mode:write sgm chip LSB bit error\n",__func__); } //backlight_i2c_write(data,sgm_nr_data[0][0],sgm_nr_data[0][1]); //write LSB - ret = backlight_i2c_write(data,sgm_nr_data[1][0],sgm_nr_data[1][1]); //write MSB + ret = backlight_i2c_write(sgm,sgm_nr_data[1][0],sgm_nr_data[1][1]); //write MSB if(ret < 0){ pr_err("%s:NR mode:write sgm chip MSB error\n",__func__); } - mutex_unlock(&data->lock); + mutex_unlock(&sgm->lock); } else{ dev_err(&client->dev,"wrong chipid\n"); @@ -308,22 +417,32 @@ static int sgm37603a_probe(struct i2c_client *client, dev_err(&bd->dev,"Unable to create backlight_i2c_attribute\n"); goto kfree_sysfs; } +#if defined(CONFIG_FB) + sgm->fb_notif.notifier_call = fb_notifier_callback; + ret = fb_register_client(&sgm->fb_notif); + if (ret) { + pr_err("Unable to register fb_notifier: %d\n", ret); + goto err_register_fb_notif_failed; + } +#endif return 0; - +#if defined(CONFIG_FB) +err_register_fb_notif_failed: +#endif kfree_sysfs: sysfs_remove_group(&bd->dev.kobj, &sgm37603a_attribute_group); kfree_node: backlight_device_unregister(bd); kfree_exit: - mutex_destroy(&data->lock); + mutex_destroy(&sgm->lock); return ret; } static int sgm37603a_remove(struct i2c_client *client) { - struct sgm37603a_data *data = sgmdata; + struct sgm37603a_data *sgm = sgmdata; if(sgmdata != NULL) - mutex_destroy(&data->lock); + mutex_destroy(&sgm->lock); sysfs_remove_group(&bd->dev.kobj, &sgm37603a_attribute_group); backlight_device_unregister(bd); return 0; @@ -358,6 +477,7 @@ static int __init sgm37603a_init(void) pr_info("sgm37603a_init\n"); ret = i2c_add_driver(&sgm37603a_driver); + pr_info("sgm37603a_init ret=%d\n",ret); if(ret){ pr_err("fail to add sgm37603 driver\n"); return ret; @@ -376,4 +496,4 @@ MODULE_DESCRIPTION("LCD_BACKLIGHT davicom ic driver"); MODULE_LICENSE("GPL"); module_init(sgm37603a_init); -module_exit(sgm37603a_exit); \ No newline at end of file +module_exit(sgm37603a_exit); diff --git a/drivers/video/backlight/sgm37603a.h b/drivers/video/backlight/sgm37603a.h index 2c4acf301058..d9eb25a5692b 100755 --- a/drivers/video/backlight/sgm37603a.h +++ b/drivers/video/backlight/sgm37603a.h @@ -37,6 +37,10 @@ struct sgm37603a_data { struct mutex lock; unsigned char mode; char* name; +#if defined(CONFIG_FB) + struct notifier_block fb_notif; +#endif + unsigned char is_suspend; }; unsigned char sgm_nr_data[][2]= -- 2.20.1