#include <linux/slab.h>\r
#include <linux/mutex.h>\r
#include <linux/interrupt.h>\r
+#ifdef CONFIG_FB\r
+#include <linux/notifier.h>\r
+#endif\r
#ifdef CONFIG_OF\r
#include <linux/of_gpio.h>\r
#endif\r
return ret;\r
}\r
\r
+ i2c_data->mode = value;\r
+\r
+ if(i2c_data->is_suspend){\r
+ pr_err("device is suspend now, set HBM mode on next power on\n");\r
+ goto exit;\r
+ }\r
+\r
pr_err("%s: current mode=%d, now write to %d\n", __func__, i2c_data->mode, value);\r
\r
if(1 == value){\r
- mutex_lock(&i2c_data->lock);\r
+ if(mutex_trylock(&i2c_data->lock)==0){\r
+ pr_err("%s: lm36923 dev is busy\n",__func__);\r
+ goto exit;\r
+ }\r
+\r
ret = backlight_i2c_write_bits(i2c_data,lm_hl_data[0][0],LM_LSB_MASK,lm_hl_data[0][1]); //write LSB\r
if(ret < 0){\r
pr_err("HL mode:write lm chip LSB bit error\n");\r
mutex_unlock(&i2c_data->lock);\r
goto exit;\r
}\r
- i2c_data->mode = value;\r
mutex_unlock(&i2c_data->lock);\r
}\r
else if(0 == value){\r
- mutex_lock(&i2c_data->lock);\r
+ if(mutex_trylock(&i2c_data->lock)==0){\r
+ pr_err("%s: lm36923 dev is busy\n",__func__);\r
+ goto exit;\r
+ }\r
+\r
ret = backlight_i2c_write_bits(i2c_data,lm_nr_data[0][0],LM_LSB_MASK,lm_nr_data[0][1]); //write LSB\r
if(ret < 0){\r
pr_err("NR mode:write lm chip LSB bit error\n");\r
mutex_unlock(&i2c_data->lock);\r
goto exit;\r
}\r
- i2c_data->mode = value;\r
mutex_unlock(&i2c_data->lock);\r
}\r
else{\r
return (value&BACKLIGHT_CHIP_ID_REG_MASK)>>4;\r
}\r
\r
-\r
+#if defined(CONFIG_FB)\r
+static int lm36923_resume(struct lm36923_data *dev_data)\r
+{\r
+ int ret = 0;\r
+ dev_data->is_suspend = 0;\r
+ if (!dev_data) {\r
+ pr_err("%s: kzalloc error\n",__func__);\r
+ return -ENOMEM;\r
+ }\r
+ pr_info("%s:now write mode to %d\n",__func__,dev_data->mode);\r
+ if(1 == dev_data->mode){\r
+ if(mutex_trylock(&dev_data->lock)==0){\r
+ pr_err("%s: lm36923 dev is busy\n",__func__);\r
+ goto exit;\r
+ }\r
+\r
+ ret = backlight_i2c_write_bits(dev_data,lm_hl_data[0][0],LM_LSB_MASK,lm_hl_data[0][1]); //write LSB\r
+ if(ret < 0){\r
+ pr_err("HL mode:write sgm chip LSB bit error\n");\r
+ mutex_unlock(&dev_data->lock);\r
+ goto exit;\r
+ }\r
+\r
+ ret = backlight_i2c_write(dev_data,lm_hl_data[1][0],lm_hl_data[1][1]); //write MSB\r
+ if(ret < 0){\r
+ pr_err("HL mode:write sgm chip MSB error\n");\r
+ mutex_unlock(&dev_data->lock);\r
+ goto exit;\r
+ }\r
+ mutex_unlock(&dev_data->lock);\r
+ }else if(0 == dev_data->mode){\r
+ if(mutex_trylock(&dev_data->lock)==0){\r
+ pr_err("%s: lm36923 dev is busy\n",__func__);\r
+ goto exit;\r
+ }\r
+\r
+ ret = backlight_i2c_write_bits(dev_data,lm_nr_data[0][0],LM_LSB_MASK,lm_nr_data[0][1]); //write LSB\r
+ if(ret < 0){\r
+ pr_err("NR mode:write sgm chip LSB bit error\n");\r
+ mutex_unlock(&dev_data->lock);\r
+ goto exit;\r
+ }\r
+\r
+ ret = backlight_i2c_write(dev_data,lm_nr_data[1][0],lm_nr_data[1][1]); //write MSB\r
+ if(ret < 0){\r
+ pr_err("NR mode:write sgm chip MSB error\n");\r
+ mutex_unlock(&dev_data->lock);\r
+ goto exit;\r
+ }\r
+ mutex_unlock(&dev_data->lock);\r
+ }\r
+ else{\r
+ pr_err("the error echo value, 0 or 1 is allowed only\n");\r
+ }\r
+exit:\r
+ return ret;\r
+}\r
+static int lm36923_suspend(struct lm36923_data *dev_data)\r
+{\r
+ int ret = 0;\r
+ dev_data->is_suspend = 1;\r
+ return ret;\r
+}\r
+static int fb_notifier_callback(struct notifier_block *self,\r
+ unsigned long event, void *data)\r
+{\r
+ int *blank;\r
+ struct fb_event *evdata = data;\r
+ struct lm36923_data *lm =\r
+ container_of(self, struct lm36923_data, fb_notif);\r
+\r
+ if (evdata && evdata->data && event == FB_EVENT_BLANK ) {\r
+ blank = evdata->data;\r
+ switch (*blank) {\r
+ case FB_BLANK_UNBLANK:\r
+ lm36923_resume(lm);\r
+ break;\r
+ case FB_BLANK_POWERDOWN:\r
+ case FB_BLANK_HSYNC_SUSPEND:\r
+ case FB_BLANK_VSYNC_SUSPEND:\r
+ case FB_BLANK_NORMAL:\r
+ lm36923_suspend(lm);\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+ return 0;\r
+}\r
+#endif\r
static int lm36923_probe(struct i2c_client *client,\r
const struct i2c_device_id *id)\r
{\r
int ret = 0;\r
- struct lm36923_data *data;\r
+ struct lm36923_data *lm;\r
struct device_node *np=client->dev.of_node;\r
\r
pr_err("%s: enter\n",__func__);\r
return -EIO;\r
}\r
\r
- data = devm_kzalloc(&client->dev,sizeof(struct lm36923_data), GFP_KERNEL);\r
- if (!data) {\r
+ lm = devm_kzalloc(&client->dev,sizeof(struct lm36923_data), GFP_KERNEL);\r
+ if (!lm) {\r
pr_err("%s: kzalloc error\n",__func__);\r
return -ENOMEM;\r
}\r
\r
- data->bk_i2c_client = client;\r
- mutex_init(&data->lock);\r
- data->mode = 0;\r
+ lm->bk_i2c_client = client;\r
+ mutex_init(&lm->lock);\r
+ lm->mode = 0;\r
+ lm->is_suspend = 0;\r
\r
- i2c_set_clientdata(client, data);\r
- lmdata=data;\r
+ i2c_set_clientdata(client, lm);\r
+ lmdata=lm;\r
\r
if (np) {\r
- ret = lm36923_parse_dt(&client->dev, data, np);\r
+ ret = lm36923_parse_dt(&client->dev, lm, np);\r
if (ret) {\r
dev_err(&client->dev,"Unable to parse platfrom data err=%d\n", ret);\r
goto kfree_exit;\r
\r
if(0==chipid){\r
printk(KERN_ERR "lm36923 chip\n");\r
- mutex_lock(&data->lock);\r
- data->name="lm36923\0";\r
- ret = backlight_i2c_write_bits(data,lm_nr_data[0][0],LM_LSB_MASK,lm_nr_data[0][1]);\r
+ mutex_lock(&lm->lock);\r
+ lm->name="lm36923\0";\r
+ ret = backlight_i2c_write_bits(lm,lm_nr_data[0][0],LM_LSB_MASK,lm_nr_data[0][1]);\r
if(ret < 0){\r
pr_err("%s:NR mode:write lm chip LSB bit error\n",__func__);\r
}\r
\r
- ret = backlight_i2c_write(data,lm_nr_data[1][0],lm_nr_data[1][1]); //write MSB\r
+ ret = backlight_i2c_write(lm,lm_nr_data[1][0],lm_nr_data[1][1]); //write MSB\r
if(ret < 0){\r
pr_err("%s:NR mode:write lm chip MSB error\n",__func__);\r
}\r
- mutex_unlock(&data->lock);\r
+ mutex_unlock(&lm->lock);\r
}\r
else{\r
dev_err(&client->dev,"wrong chipid\n");\r
dev_err(&bd->dev,"Unable to create backlight_i2c_attribute\n");\r
goto kfree_sysfs;\r
}\r
+#if defined(CONFIG_FB)\r
+ lm->fb_notif.notifier_call = fb_notifier_callback;\r
+ ret = fb_register_client(&lm->fb_notif);\r
+ if (ret) {\r
+ pr_err("Unable to register fb_notifier: %d\n", ret);\r
+ goto err_register_fb_notif_failed;\r
+ }\r
+#endif\r
return 0;\r
-\r
+#if defined(CONFIG_FB)\r
+err_register_fb_notif_failed:\r
+#endif\r
kfree_sysfs:\r
sysfs_remove_group(&bd->dev.kobj, &lm36923_attribute_group);\r
kfree_node:\r
backlight_device_unregister(bd);\r
kfree_exit:\r
- mutex_destroy(&data->lock);\r
+ mutex_destroy(&lm->lock);\r
return ret;\r
}\r
\r
static int lm36923_remove(struct i2c_client *client)\r
{\r
- struct lm36923_data *data = lmdata;\r
+ struct lm36923_data *lm = lmdata;\r
if(lmdata != NULL)\r
- mutex_destroy(&data->lock);\r
+ mutex_destroy(&lm->lock);\r
sysfs_remove_group(&bd->dev.kobj, &lm36923_attribute_group);\r
backlight_device_unregister(bd);\r
return 0;\r
MODULE_LICENSE("GPL");\r
\r
module_init(lm36923_init);\r
-module_exit(lm36923_exit);
\ No newline at end of file
+module_exit(lm36923_exit);\r
#include <linux/slab.h>\r
#include <linux/mutex.h>\r
#include <linux/interrupt.h>\r
+#if defined(CONFIG_FB)\r
+#include <linux/notifier.h>\r
+#endif\r
#ifdef CONFIG_OF\r
#include <linux/of_gpio.h>\r
#endif\r
return ret;\r
}\r
\r
+ i2c_data->mode = value;\r
+\r
+ if(i2c_data->is_suspend){\r
+ pr_err("device is suspend now, set HBM mode on next power on\n");\r
+ goto exit;\r
+ }\r
+\r
pr_err("%s: current mode=%d, now write to %d\n", __func__, i2c_data->mode, value);\r
\r
if(1 == value){\r
- mutex_lock(&i2c_data->lock);\r
+ if(mutex_trylock(&i2c_data->lock)==0){\r
+ pr_err("%s: sgm37603a dev is busy\n",__func__);\r
+ goto exit;\r
+ }\r
+\r
ret = backlight_i2c_write_bits(i2c_data,sgm_hl_data[0][0],SGM_LSB_MASK,sgm_hl_data[0][1]); //write LSB\r
if(ret < 0){\r
pr_err("HL mode:write sgm chip LSB bit error\n");\r
mutex_unlock(&i2c_data->lock);\r
goto exit;\r
}\r
- i2c_data->mode = value;\r
mutex_unlock(&i2c_data->lock);\r
}\r
else if(0 == value){\r
- mutex_lock(&i2c_data->lock);\r
+ if(mutex_trylock(&i2c_data->lock)==0){\r
+ pr_err("%s: sgm37603a dev is busy\n",__func__);\r
+ goto exit;\r
+ }\r
+\r
ret = backlight_i2c_write_bits(i2c_data,sgm_nr_data[0][0],SGM_LSB_MASK,sgm_nr_data[0][1]); //write LSB\r
if(ret < 0){\r
pr_err("NR mode:write sgm chip LSB bit error\n");\r
mutex_unlock(&i2c_data->lock);\r
goto exit;\r
}\r
- i2c_data->mode = value;\r
mutex_unlock(&i2c_data->lock);\r
}\r
else{\r
int ret = -1;\r
unsigned char reg;\r
unsigned char val;\r
- struct sgm37603a_data *i2c_data = sgmdata;\r
- \r
+ struct sgm37603a_data *i2c_data = sgmdata;\r\r
+\r
if(!count || i2c_data==NULL){\r
pr_err("%s:count=0 or i2c_data is NULL pointer\n",__func__);\r
return -EINVAL;\r
return (value&BACKLIGHT_CHIP_ID_REG_MASK)>>4;\r
}\r
\r
+#if defined(CONFIG_FB)\r
+static int sgm37603a_resume(struct sgm37603a_data *dev_data)\r
+{\r
+ int ret = 0;\r
+\r
+ dev_data->is_suspend = 0;\r
+ if (!dev_data) {\r
+ pr_err("%s: kzalloc error\n",__func__);\r
+ return -ENOMEM;\r
+ }\r
\r
+ pr_info("%s:now write mode to %d\n",__func__,dev_data->mode);\r
+ if(1 == dev_data->mode){\r
+ if(mutex_trylock(&dev_data->lock)==0){\r
+ pr_err("%s: sgm37603a dev is busy\n",__func__);\r
+ goto exit;\r
+ }\r
+\r
+ ret = backlight_i2c_write_bits(dev_data,sgm_hl_data[0][0],SGM_LSB_MASK,sgm_hl_data[0][1]); //write LSB\r
+ if(ret < 0){\r
+ pr_err("HL mode:write sgm chip LSB bit error\n");\r
+ mutex_unlock(&dev_data->lock);\r
+ goto exit;\r
+ }\r
+\r
+ ret = backlight_i2c_write(dev_data,sgm_hl_data[1][0],sgm_hl_data[1][1]); //write MSB\r
+ if(ret < 0){\r
+ pr_err("HL mode:write sgm chip MSB error\n");\r
+ mutex_unlock(&dev_data->lock);\r
+ goto exit;\r
+ }\r
+ mutex_unlock(&dev_data->lock);\r
+ }else if(0 == dev_data->mode){\r
+ if(mutex_trylock(&dev_data->lock)==0){\r
+ pr_err("%s: sgm37603a dev is busy\n",__func__);\r
+ goto exit;\r
+ }\r
+\r
+ ret = backlight_i2c_write_bits(dev_data,sgm_nr_data[0][0],SGM_LSB_MASK,sgm_nr_data[0][1]); //write LSB\r
+ if(ret < 0){\r
+ pr_err("NR mode:write sgm chip LSB bit error\n");\r
+ mutex_unlock(&dev_data->lock);\r
+ goto exit;\r
+ }\r
+\r
+ ret = backlight_i2c_write(dev_data,sgm_nr_data[1][0],sgm_nr_data[1][1]); //write MSB\r
+ if(ret < 0){\r
+ pr_err("NR mode:write sgm chip MSB error\n");\r
+ mutex_unlock(&dev_data->lock);\r
+ goto exit;\r
+ }\r
+ mutex_unlock(&dev_data->lock);\r
+ }\r
+ else{\r
+ pr_err("the error echo value, 0 or 1 is allowed only\n");\r
+ }\r
+exit:\r
+ return ret;\r
+}
+static int sgm37603a_suspend(struct sgm37603a_data *dev_data)\r
+{\r
+ int ret = 0;\r
+ dev_data->is_suspend = 1;\r
+ return ret;\r
+}\r
+\r
+static int fb_notifier_callback(struct notifier_block *self,
+ unsigned long event, void *data)
+{
+ int *blank;\r
+ struct fb_event *evdata = data;\r
+ struct sgm37603a_data *sgm =\r
+ container_of(self, struct sgm37603a_data, fb_notif);\r
+\r
+ if (evdata && evdata->data && event == FB_EVENT_BLANK ) {\r
+ blank = evdata->data;\r
+ switch (*blank) {\r
+ case FB_BLANK_UNBLANK:\r
+ sgm37603a_resume(sgm);\r
+ break;\r
+ case FB_BLANK_POWERDOWN:\r
+ case FB_BLANK_HSYNC_SUSPEND:\r
+ case FB_BLANK_VSYNC_SUSPEND:\r
+ case FB_BLANK_NORMAL:\r
+ sgm37603a_suspend(sgm);\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+ return 0;\r
+}
+#endif\r
static int sgm37603a_probe(struct i2c_client *client,\r
const struct i2c_device_id *id)\r
{\r
int ret = 0;\r
- struct sgm37603a_data *data;\r
+ struct sgm37603a_data *sgm;\r
struct device_node *np=client->dev.of_node;\r
\r
pr_err("%s: enter\n",__func__);\r
return -EIO;\r
}\r
\r
- data = devm_kzalloc(&client->dev,sizeof(struct sgm37603a_data), GFP_KERNEL);\r
- if (!data) {\r
+ sgm = devm_kzalloc(&client->dev,sizeof(struct sgm37603a_data), GFP_KERNEL);\r
+ if (!sgm) {\r
pr_err("%s: kzalloc error\n",__func__);\r
return -ENOMEM;\r
}\r
\r
- data->bk_i2c_client = client;\r
- mutex_init(&data->lock);\r
- data->mode = 0;\r
- i2c_set_clientdata(client, data);\r
- sgmdata=data;\r
+ sgm->bk_i2c_client = client;\r
+ mutex_init(&sgm->lock);\r
+ sgm->mode = 0;\r
+ sgm->is_suspend = 0;\r
+ i2c_set_clientdata(client, sgm);\r
+ sgmdata=sgm;\r
\r
if (np) {\r
- ret = sgm37603a_parse_dt(&client->dev, data, np);\r
+ ret = sgm37603a_parse_dt(&client->dev, sgm, np);\r
if (ret) {\r
dev_err(&client->dev,"Unable to parse platfrom data err=%d\n", ret);\r
goto kfree_exit;\r
\r
if(1==chipid){\r
printk(KERN_ERR "sgm37603 chip\n");\r
- mutex_lock(&data->lock);\r
- data->name="sgm37603\0";\r
- ret = backlight_i2c_write_bits(data,sgm_nr_data[0][0],SGM_LSB_MASK,sgm_nr_data[0][1]);\r
+ mutex_lock(&sgm->lock);\r
+ sgm->name="sgm37603\0";\r
+ ret = backlight_i2c_write_bits(sgm,sgm_nr_data[0][0],SGM_LSB_MASK,sgm_nr_data[0][1]);\r
if(ret < 0){\r
pr_err("%s:NR mode:write sgm chip LSB bit error\n",__func__);\r
}\r
//backlight_i2c_write(data,sgm_nr_data[0][0],sgm_nr_data[0][1]); //write LSB\r
- ret = backlight_i2c_write(data,sgm_nr_data[1][0],sgm_nr_data[1][1]); //write MSB\r
+ ret = backlight_i2c_write(sgm,sgm_nr_data[1][0],sgm_nr_data[1][1]); //write MSB\r
if(ret < 0){\r
pr_err("%s:NR mode:write sgm chip MSB error\n",__func__);\r
}\r
- mutex_unlock(&data->lock);\r
+ mutex_unlock(&sgm->lock);\r
}\r
else{\r
dev_err(&client->dev,"wrong chipid\n");\r
dev_err(&bd->dev,"Unable to create backlight_i2c_attribute\n");\r
goto kfree_sysfs;\r
}\r
+#if defined(CONFIG_FB)\r
+ sgm->fb_notif.notifier_call = fb_notifier_callback;\r
+ ret = fb_register_client(&sgm->fb_notif);\r
+ if (ret) {\r
+ pr_err("Unable to register fb_notifier: %d\n", ret);\r
+ goto err_register_fb_notif_failed;\r
+ }\r
+#endif\r
return 0;\r
- \r
+#if defined(CONFIG_FB)
+err_register_fb_notif_failed:\r
+#endif\r
kfree_sysfs:\r
sysfs_remove_group(&bd->dev.kobj, &sgm37603a_attribute_group);\r
kfree_node:\r
backlight_device_unregister(bd);\r
kfree_exit:\r
- mutex_destroy(&data->lock);\r
+ mutex_destroy(&sgm->lock);\r
return ret;\r
}\r
\r
static int sgm37603a_remove(struct i2c_client *client)\r
{\r
- struct sgm37603a_data *data = sgmdata;\r
+ struct sgm37603a_data *sgm = sgmdata;\r
if(sgmdata != NULL)\r
- mutex_destroy(&data->lock);\r
+ mutex_destroy(&sgm->lock);\r
sysfs_remove_group(&bd->dev.kobj, &sgm37603a_attribute_group);\r
backlight_device_unregister(bd);\r
return 0;\r
pr_info("sgm37603a_init\n");\r
\r
ret = i2c_add_driver(&sgm37603a_driver);\r
+ pr_info("sgm37603a_init ret=%d\n",ret);\r
if(ret){\r
pr_err("fail to add sgm37603 driver\n");\r
return ret;\r
MODULE_LICENSE("GPL");\r
\r
module_init(sgm37603a_init);\r
-module_exit(sgm37603a_exit);
\ No newline at end of file
+module_exit(sgm37603a_exit);\r