18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * sky81452-backlight.c SKY81452 backlight driver 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright 2014 Skyworks Solutions Inc. 68c2ecf20Sopenharmony_ci * Author : Gyungoh Yoo <jack.yoo@skyworksinc.com> 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include <linux/backlight.h> 108c2ecf20Sopenharmony_ci#include <linux/err.h> 118c2ecf20Sopenharmony_ci#include <linux/gpio/consumer.h> 128c2ecf20Sopenharmony_ci#include <linux/init.h> 138c2ecf20Sopenharmony_ci#include <linux/kernel.h> 148c2ecf20Sopenharmony_ci#include <linux/module.h> 158c2ecf20Sopenharmony_ci#include <linux/of.h> 168c2ecf20Sopenharmony_ci#include <linux/platform_device.h> 178c2ecf20Sopenharmony_ci#include <linux/regmap.h> 188c2ecf20Sopenharmony_ci#include <linux/slab.h> 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci/* registers */ 218c2ecf20Sopenharmony_ci#define SKY81452_REG0 0x00 228c2ecf20Sopenharmony_ci#define SKY81452_REG1 0x01 238c2ecf20Sopenharmony_ci#define SKY81452_REG2 0x02 248c2ecf20Sopenharmony_ci#define SKY81452_REG4 0x04 258c2ecf20Sopenharmony_ci#define SKY81452_REG5 0x05 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci/* bit mask */ 288c2ecf20Sopenharmony_ci#define SKY81452_CS 0xFF 298c2ecf20Sopenharmony_ci#define SKY81452_EN 0x3F 308c2ecf20Sopenharmony_ci#define SKY81452_IGPW 0x20 318c2ecf20Sopenharmony_ci#define SKY81452_PWMMD 0x10 328c2ecf20Sopenharmony_ci#define SKY81452_PHASE 0x08 338c2ecf20Sopenharmony_ci#define SKY81452_ILIM 0x04 348c2ecf20Sopenharmony_ci#define SKY81452_VSHRT 0x03 358c2ecf20Sopenharmony_ci#define SKY81452_OCP 0x80 368c2ecf20Sopenharmony_ci#define SKY81452_OTMP 0x40 378c2ecf20Sopenharmony_ci#define SKY81452_SHRT 0x3F 388c2ecf20Sopenharmony_ci#define SKY81452_OPN 0x3F 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci#define SKY81452_DEFAULT_NAME "lcd-backlight" 418c2ecf20Sopenharmony_ci#define SKY81452_MAX_BRIGHTNESS (SKY81452_CS + 1) 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci/** 448c2ecf20Sopenharmony_ci * struct sky81452_platform_data 458c2ecf20Sopenharmony_ci * @name: backlight driver name. 468c2ecf20Sopenharmony_ci * If it is not defined, default name is lcd-backlight. 478c2ecf20Sopenharmony_ci * @gpiod_enable:GPIO descriptor which control EN pin 488c2ecf20Sopenharmony_ci * @enable: Enable mask for current sink channel 1, 2, 3, 4, 5 and 6. 498c2ecf20Sopenharmony_ci * @ignore_pwm: true if DPWMI should be ignored. 508c2ecf20Sopenharmony_ci * @dpwm_mode: true is DPWM dimming mode, otherwise Analog dimming mode. 518c2ecf20Sopenharmony_ci * @phase_shift:true is phase shift mode. 528c2ecf20Sopenharmony_ci * @short_detection_threshold: It should be one of 4, 5, 6 and 7V. 538c2ecf20Sopenharmony_ci * @boost_current_limit: It should be one of 2300, 2750mA. 548c2ecf20Sopenharmony_ci */ 558c2ecf20Sopenharmony_cistruct sky81452_bl_platform_data { 568c2ecf20Sopenharmony_ci const char *name; 578c2ecf20Sopenharmony_ci struct gpio_desc *gpiod_enable; 588c2ecf20Sopenharmony_ci unsigned int enable; 598c2ecf20Sopenharmony_ci bool ignore_pwm; 608c2ecf20Sopenharmony_ci bool dpwm_mode; 618c2ecf20Sopenharmony_ci bool phase_shift; 628c2ecf20Sopenharmony_ci unsigned int short_detection_threshold; 638c2ecf20Sopenharmony_ci unsigned int boost_current_limit; 648c2ecf20Sopenharmony_ci}; 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci#define CTZ(b) __builtin_ctz(b) 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_cistatic int sky81452_bl_update_status(struct backlight_device *bd) 698c2ecf20Sopenharmony_ci{ 708c2ecf20Sopenharmony_ci const struct sky81452_bl_platform_data *pdata = 718c2ecf20Sopenharmony_ci dev_get_platdata(bd->dev.parent); 728c2ecf20Sopenharmony_ci const unsigned int brightness = (unsigned int)bd->props.brightness; 738c2ecf20Sopenharmony_ci struct regmap *regmap = bl_get_data(bd); 748c2ecf20Sopenharmony_ci int ret; 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci if (brightness > 0) { 778c2ecf20Sopenharmony_ci ret = regmap_write(regmap, SKY81452_REG0, brightness - 1); 788c2ecf20Sopenharmony_ci if (ret < 0) 798c2ecf20Sopenharmony_ci return ret; 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci return regmap_update_bits(regmap, SKY81452_REG1, SKY81452_EN, 828c2ecf20Sopenharmony_ci pdata->enable << CTZ(SKY81452_EN)); 838c2ecf20Sopenharmony_ci } 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci return regmap_update_bits(regmap, SKY81452_REG1, SKY81452_EN, 0); 868c2ecf20Sopenharmony_ci} 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_cistatic const struct backlight_ops sky81452_bl_ops = { 898c2ecf20Sopenharmony_ci .update_status = sky81452_bl_update_status, 908c2ecf20Sopenharmony_ci}; 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_cistatic ssize_t sky81452_bl_store_enable(struct device *dev, 938c2ecf20Sopenharmony_ci struct device_attribute *attr, const char *buf, size_t count) 948c2ecf20Sopenharmony_ci{ 958c2ecf20Sopenharmony_ci struct regmap *regmap = bl_get_data(to_backlight_device(dev)); 968c2ecf20Sopenharmony_ci unsigned long value; 978c2ecf20Sopenharmony_ci int ret; 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci ret = kstrtoul(buf, 16, &value); 1008c2ecf20Sopenharmony_ci if (ret < 0) 1018c2ecf20Sopenharmony_ci return ret; 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci ret = regmap_update_bits(regmap, SKY81452_REG1, SKY81452_EN, 1048c2ecf20Sopenharmony_ci value << CTZ(SKY81452_EN)); 1058c2ecf20Sopenharmony_ci if (ret < 0) 1068c2ecf20Sopenharmony_ci return ret; 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci return count; 1098c2ecf20Sopenharmony_ci} 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_cistatic ssize_t sky81452_bl_show_open_short(struct device *dev, 1128c2ecf20Sopenharmony_ci struct device_attribute *attr, char *buf) 1138c2ecf20Sopenharmony_ci{ 1148c2ecf20Sopenharmony_ci struct regmap *regmap = bl_get_data(to_backlight_device(dev)); 1158c2ecf20Sopenharmony_ci unsigned int reg, value = 0; 1168c2ecf20Sopenharmony_ci char tmp[3]; 1178c2ecf20Sopenharmony_ci int i, ret; 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci reg = !strcmp(attr->attr.name, "open") ? SKY81452_REG5 : SKY81452_REG4; 1208c2ecf20Sopenharmony_ci ret = regmap_read(regmap, reg, &value); 1218c2ecf20Sopenharmony_ci if (ret < 0) 1228c2ecf20Sopenharmony_ci return ret; 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ci if (value & SKY81452_SHRT) { 1258c2ecf20Sopenharmony_ci *buf = 0; 1268c2ecf20Sopenharmony_ci for (i = 0; i < 6; i++) { 1278c2ecf20Sopenharmony_ci if (value & 0x01) { 1288c2ecf20Sopenharmony_ci sprintf(tmp, "%d ", i + 1); 1298c2ecf20Sopenharmony_ci strcat(buf, tmp); 1308c2ecf20Sopenharmony_ci } 1318c2ecf20Sopenharmony_ci value >>= 1; 1328c2ecf20Sopenharmony_ci } 1338c2ecf20Sopenharmony_ci strcat(buf, "\n"); 1348c2ecf20Sopenharmony_ci } else { 1358c2ecf20Sopenharmony_ci strcpy(buf, "none\n"); 1368c2ecf20Sopenharmony_ci } 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci return strlen(buf); 1398c2ecf20Sopenharmony_ci} 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_cistatic ssize_t sky81452_bl_show_fault(struct device *dev, 1428c2ecf20Sopenharmony_ci struct device_attribute *attr, char *buf) 1438c2ecf20Sopenharmony_ci{ 1448c2ecf20Sopenharmony_ci struct regmap *regmap = bl_get_data(to_backlight_device(dev)); 1458c2ecf20Sopenharmony_ci unsigned int value = 0; 1468c2ecf20Sopenharmony_ci int ret; 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci ret = regmap_read(regmap, SKY81452_REG4, &value); 1498c2ecf20Sopenharmony_ci if (ret < 0) 1508c2ecf20Sopenharmony_ci return ret; 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci *buf = 0; 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ci if (value & SKY81452_OCP) 1558c2ecf20Sopenharmony_ci strcat(buf, "over-current "); 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci if (value & SKY81452_OTMP) 1588c2ecf20Sopenharmony_ci strcat(buf, "over-temperature"); 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_ci strcat(buf, "\n"); 1618c2ecf20Sopenharmony_ci return strlen(buf); 1628c2ecf20Sopenharmony_ci} 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_cistatic DEVICE_ATTR(enable, S_IWGRP | S_IWUSR, NULL, sky81452_bl_store_enable); 1658c2ecf20Sopenharmony_cistatic DEVICE_ATTR(open, S_IRUGO, sky81452_bl_show_open_short, NULL); 1668c2ecf20Sopenharmony_cistatic DEVICE_ATTR(short, S_IRUGO, sky81452_bl_show_open_short, NULL); 1678c2ecf20Sopenharmony_cistatic DEVICE_ATTR(fault, S_IRUGO, sky81452_bl_show_fault, NULL); 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_cistatic struct attribute *sky81452_bl_attribute[] = { 1708c2ecf20Sopenharmony_ci &dev_attr_enable.attr, 1718c2ecf20Sopenharmony_ci &dev_attr_open.attr, 1728c2ecf20Sopenharmony_ci &dev_attr_short.attr, 1738c2ecf20Sopenharmony_ci &dev_attr_fault.attr, 1748c2ecf20Sopenharmony_ci NULL 1758c2ecf20Sopenharmony_ci}; 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_cistatic const struct attribute_group sky81452_bl_attr_group = { 1788c2ecf20Sopenharmony_ci .attrs = sky81452_bl_attribute, 1798c2ecf20Sopenharmony_ci}; 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci#ifdef CONFIG_OF 1828c2ecf20Sopenharmony_cistatic struct sky81452_bl_platform_data *sky81452_bl_parse_dt( 1838c2ecf20Sopenharmony_ci struct device *dev) 1848c2ecf20Sopenharmony_ci{ 1858c2ecf20Sopenharmony_ci struct device_node *np = of_node_get(dev->of_node); 1868c2ecf20Sopenharmony_ci struct sky81452_bl_platform_data *pdata; 1878c2ecf20Sopenharmony_ci int num_entry; 1888c2ecf20Sopenharmony_ci unsigned int sources[6]; 1898c2ecf20Sopenharmony_ci int ret; 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_ci if (!np) { 1928c2ecf20Sopenharmony_ci dev_err(dev, "backlight node not found.\n"); 1938c2ecf20Sopenharmony_ci return ERR_PTR(-ENODATA); 1948c2ecf20Sopenharmony_ci } 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ci pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); 1978c2ecf20Sopenharmony_ci if (!pdata) { 1988c2ecf20Sopenharmony_ci of_node_put(np); 1998c2ecf20Sopenharmony_ci return ERR_PTR(-ENOMEM); 2008c2ecf20Sopenharmony_ci } 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_ci of_property_read_string(np, "name", &pdata->name); 2038c2ecf20Sopenharmony_ci pdata->ignore_pwm = of_property_read_bool(np, "skyworks,ignore-pwm"); 2048c2ecf20Sopenharmony_ci pdata->dpwm_mode = of_property_read_bool(np, "skyworks,dpwm-mode"); 2058c2ecf20Sopenharmony_ci pdata->phase_shift = of_property_read_bool(np, "skyworks,phase-shift"); 2068c2ecf20Sopenharmony_ci pdata->gpiod_enable = devm_gpiod_get_optional(dev, NULL, GPIOD_OUT_HIGH); 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_ci ret = of_property_count_u32_elems(np, "led-sources"); 2098c2ecf20Sopenharmony_ci if (ret < 0) { 2108c2ecf20Sopenharmony_ci pdata->enable = SKY81452_EN >> CTZ(SKY81452_EN); 2118c2ecf20Sopenharmony_ci } else { 2128c2ecf20Sopenharmony_ci num_entry = ret; 2138c2ecf20Sopenharmony_ci if (num_entry > 6) 2148c2ecf20Sopenharmony_ci num_entry = 6; 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci ret = of_property_read_u32_array(np, "led-sources", sources, 2178c2ecf20Sopenharmony_ci num_entry); 2188c2ecf20Sopenharmony_ci if (ret < 0) { 2198c2ecf20Sopenharmony_ci dev_err(dev, "led-sources node is invalid.\n"); 2208c2ecf20Sopenharmony_ci of_node_put(np); 2218c2ecf20Sopenharmony_ci return ERR_PTR(-EINVAL); 2228c2ecf20Sopenharmony_ci } 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci pdata->enable = 0; 2258c2ecf20Sopenharmony_ci while (--num_entry) 2268c2ecf20Sopenharmony_ci pdata->enable |= (1 << sources[num_entry]); 2278c2ecf20Sopenharmony_ci } 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ci ret = of_property_read_u32(np, 2308c2ecf20Sopenharmony_ci "skyworks,short-detection-threshold-volt", 2318c2ecf20Sopenharmony_ci &pdata->short_detection_threshold); 2328c2ecf20Sopenharmony_ci if (ret < 0) 2338c2ecf20Sopenharmony_ci pdata->short_detection_threshold = 7; 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci ret = of_property_read_u32(np, "skyworks,current-limit-mA", 2368c2ecf20Sopenharmony_ci &pdata->boost_current_limit); 2378c2ecf20Sopenharmony_ci if (ret < 0) 2388c2ecf20Sopenharmony_ci pdata->boost_current_limit = 2750; 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_ci of_node_put(np); 2418c2ecf20Sopenharmony_ci return pdata; 2428c2ecf20Sopenharmony_ci} 2438c2ecf20Sopenharmony_ci#else 2448c2ecf20Sopenharmony_cistatic struct sky81452_bl_platform_data *sky81452_bl_parse_dt( 2458c2ecf20Sopenharmony_ci struct device *dev) 2468c2ecf20Sopenharmony_ci{ 2478c2ecf20Sopenharmony_ci return ERR_PTR(-EINVAL); 2488c2ecf20Sopenharmony_ci} 2498c2ecf20Sopenharmony_ci#endif 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_cistatic int sky81452_bl_init_device(struct regmap *regmap, 2528c2ecf20Sopenharmony_ci struct sky81452_bl_platform_data *pdata) 2538c2ecf20Sopenharmony_ci{ 2548c2ecf20Sopenharmony_ci unsigned int value; 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_ci value = pdata->ignore_pwm ? SKY81452_IGPW : 0; 2578c2ecf20Sopenharmony_ci value |= pdata->dpwm_mode ? SKY81452_PWMMD : 0; 2588c2ecf20Sopenharmony_ci value |= pdata->phase_shift ? 0 : SKY81452_PHASE; 2598c2ecf20Sopenharmony_ci 2608c2ecf20Sopenharmony_ci if (pdata->boost_current_limit == 2300) 2618c2ecf20Sopenharmony_ci value |= SKY81452_ILIM; 2628c2ecf20Sopenharmony_ci else if (pdata->boost_current_limit != 2750) 2638c2ecf20Sopenharmony_ci return -EINVAL; 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_ci if (pdata->short_detection_threshold < 4 || 2668c2ecf20Sopenharmony_ci pdata->short_detection_threshold > 7) 2678c2ecf20Sopenharmony_ci return -EINVAL; 2688c2ecf20Sopenharmony_ci value |= (7 - pdata->short_detection_threshold) << CTZ(SKY81452_VSHRT); 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_ci return regmap_write(regmap, SKY81452_REG2, value); 2718c2ecf20Sopenharmony_ci} 2728c2ecf20Sopenharmony_ci 2738c2ecf20Sopenharmony_cistatic int sky81452_bl_probe(struct platform_device *pdev) 2748c2ecf20Sopenharmony_ci{ 2758c2ecf20Sopenharmony_ci struct device *dev = &pdev->dev; 2768c2ecf20Sopenharmony_ci struct regmap *regmap = dev_get_drvdata(dev->parent); 2778c2ecf20Sopenharmony_ci struct sky81452_bl_platform_data *pdata; 2788c2ecf20Sopenharmony_ci struct backlight_device *bd; 2798c2ecf20Sopenharmony_ci struct backlight_properties props; 2808c2ecf20Sopenharmony_ci const char *name; 2818c2ecf20Sopenharmony_ci int ret; 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_ci pdata = sky81452_bl_parse_dt(dev); 2848c2ecf20Sopenharmony_ci if (IS_ERR(pdata)) 2858c2ecf20Sopenharmony_ci return PTR_ERR(pdata); 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ci ret = sky81452_bl_init_device(regmap, pdata); 2888c2ecf20Sopenharmony_ci if (ret < 0) { 2898c2ecf20Sopenharmony_ci dev_err(dev, "failed to initialize. err=%d\n", ret); 2908c2ecf20Sopenharmony_ci return ret; 2918c2ecf20Sopenharmony_ci } 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_ci memset(&props, 0, sizeof(props)); 2948c2ecf20Sopenharmony_ci props.max_brightness = SKY81452_MAX_BRIGHTNESS, 2958c2ecf20Sopenharmony_ci name = pdata->name ? pdata->name : SKY81452_DEFAULT_NAME; 2968c2ecf20Sopenharmony_ci bd = devm_backlight_device_register(dev, name, dev, regmap, 2978c2ecf20Sopenharmony_ci &sky81452_bl_ops, &props); 2988c2ecf20Sopenharmony_ci if (IS_ERR(bd)) { 2998c2ecf20Sopenharmony_ci dev_err(dev, "failed to register. err=%ld\n", PTR_ERR(bd)); 3008c2ecf20Sopenharmony_ci return PTR_ERR(bd); 3018c2ecf20Sopenharmony_ci } 3028c2ecf20Sopenharmony_ci 3038c2ecf20Sopenharmony_ci platform_set_drvdata(pdev, bd); 3048c2ecf20Sopenharmony_ci 3058c2ecf20Sopenharmony_ci ret = sysfs_create_group(&bd->dev.kobj, &sky81452_bl_attr_group); 3068c2ecf20Sopenharmony_ci if (ret < 0) { 3078c2ecf20Sopenharmony_ci dev_err(dev, "failed to create attribute. err=%d\n", ret); 3088c2ecf20Sopenharmony_ci return ret; 3098c2ecf20Sopenharmony_ci } 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_ci return ret; 3128c2ecf20Sopenharmony_ci} 3138c2ecf20Sopenharmony_ci 3148c2ecf20Sopenharmony_cistatic int sky81452_bl_remove(struct platform_device *pdev) 3158c2ecf20Sopenharmony_ci{ 3168c2ecf20Sopenharmony_ci const struct sky81452_bl_platform_data *pdata = 3178c2ecf20Sopenharmony_ci dev_get_platdata(&pdev->dev); 3188c2ecf20Sopenharmony_ci struct backlight_device *bd = platform_get_drvdata(pdev); 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_ci sysfs_remove_group(&bd->dev.kobj, &sky81452_bl_attr_group); 3218c2ecf20Sopenharmony_ci 3228c2ecf20Sopenharmony_ci bd->props.power = FB_BLANK_UNBLANK; 3238c2ecf20Sopenharmony_ci bd->props.brightness = 0; 3248c2ecf20Sopenharmony_ci backlight_update_status(bd); 3258c2ecf20Sopenharmony_ci 3268c2ecf20Sopenharmony_ci if (pdata->gpiod_enable) 3278c2ecf20Sopenharmony_ci gpiod_set_value_cansleep(pdata->gpiod_enable, 0); 3288c2ecf20Sopenharmony_ci 3298c2ecf20Sopenharmony_ci return 0; 3308c2ecf20Sopenharmony_ci} 3318c2ecf20Sopenharmony_ci 3328c2ecf20Sopenharmony_ci#ifdef CONFIG_OF 3338c2ecf20Sopenharmony_cistatic const struct of_device_id sky81452_bl_of_match[] = { 3348c2ecf20Sopenharmony_ci { .compatible = "skyworks,sky81452-backlight", }, 3358c2ecf20Sopenharmony_ci { } 3368c2ecf20Sopenharmony_ci}; 3378c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(of, sky81452_bl_of_match); 3388c2ecf20Sopenharmony_ci#endif 3398c2ecf20Sopenharmony_ci 3408c2ecf20Sopenharmony_cistatic struct platform_driver sky81452_bl_driver = { 3418c2ecf20Sopenharmony_ci .driver = { 3428c2ecf20Sopenharmony_ci .name = "sky81452-backlight", 3438c2ecf20Sopenharmony_ci .of_match_table = of_match_ptr(sky81452_bl_of_match), 3448c2ecf20Sopenharmony_ci }, 3458c2ecf20Sopenharmony_ci .probe = sky81452_bl_probe, 3468c2ecf20Sopenharmony_ci .remove = sky81452_bl_remove, 3478c2ecf20Sopenharmony_ci}; 3488c2ecf20Sopenharmony_ci 3498c2ecf20Sopenharmony_cimodule_platform_driver(sky81452_bl_driver); 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("Skyworks SKY81452 backlight driver"); 3528c2ecf20Sopenharmony_ciMODULE_AUTHOR("Gyungoh Yoo <jack.yoo@skyworksinc.com>"); 3538c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL v2"); 354