Blame view

drivers/leds/leds-ti-lmu-common.c 3.77 KB
3fce8e1eb   Dan Murphy   leds: TI LMU: Add...
1
2
3
4
5
6
7
8
9
10
11
12
  // SPDX-License-Identifier: GPL-2.0
  // Copyright 2015 Texas Instruments
  // Copyright 2018 Sebastian Reichel
  // Copyright 2018 Pavel Machek <pavel@ucw.cz>
  // TI LMU LED common framework, based on previous work from
  // Milo Kim <milo.kim@ti.com>
  
  #include <linux/bitops.h>
  #include <linux/err.h>
  #include <linux/of_device.h>
  
  #include <linux/leds-ti-lmu-common.h>
ba7eb84f7   Krzysztof Wilczynski   leds: ti-lmu-comm...
13
  static const unsigned int ramp_table[16] = {2048, 262000, 524000, 1049000,
2637fd436   Dan Murphy   leds: ti-lmu-comm...
14
15
16
  				2090000, 4194000, 8389000, 16780000, 33550000,
  				41940000, 50330000, 58720000, 67110000,
  				83880000, 100660000, 117440000};
3fce8e1eb   Dan Murphy   leds: TI LMU: Add...
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
  
  static int ti_lmu_common_update_brightness(struct ti_lmu_bank *lmu_bank,
  					   int brightness)
  {
  	struct regmap *regmap = lmu_bank->regmap;
  	u8 reg, val;
  	int ret;
  
  	/*
  	 * Brightness register update
  	 *
  	 * 11 bit dimming: update LSB bits and write MSB byte.
  	 *		   MSB brightness should be shifted.
  	 *  8 bit dimming: write MSB byte.
  	 */
  	if (lmu_bank->max_brightness == MAX_BRIGHTNESS_11BIT) {
  		reg = lmu_bank->lsb_brightness_reg;
  		ret = regmap_update_bits(regmap, reg,
  					 LMU_11BIT_LSB_MASK,
  					 brightness);
  		if (ret)
  			return ret;
  
  		val = brightness >> LMU_11BIT_MSB_SHIFT;
  	} else {
  		val = brightness;
  	}
  
  	reg = lmu_bank->msb_brightness_reg;
  
  	return regmap_write(regmap, reg, val);
  }
  
  int ti_lmu_common_set_brightness(struct ti_lmu_bank *lmu_bank, int brightness)
  {
  	return ti_lmu_common_update_brightness(lmu_bank, brightness);
  }
  EXPORT_SYMBOL(ti_lmu_common_set_brightness);
2637fd436   Dan Murphy   leds: ti-lmu-comm...
55
  static unsigned int ti_lmu_common_convert_ramp_to_index(unsigned int usec)
3fce8e1eb   Dan Murphy   leds: TI LMU: Add...
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
  {
  	int size = ARRAY_SIZE(ramp_table);
  	int i;
  
  	if (usec <= ramp_table[0])
  		return 0;
  
  	if (usec > ramp_table[size - 1])
  		return size - 1;
  
  	for (i = 1; i < size; i++) {
  		if (usec == ramp_table[i])
  			return i;
  
  		/* Find an approximate index by looking up the table */
  		if (usec > ramp_table[i - 1] && usec < ramp_table[i]) {
  			if (usec - ramp_table[i - 1] < ramp_table[i] - usec)
  				return i - 1;
  			else
  				return i;
  		}
  	}
2637fd436   Dan Murphy   leds: ti-lmu-comm...
78
  	return 0;
3fce8e1eb   Dan Murphy   leds: TI LMU: Add...
79
80
81
82
83
84
85
86
87
88
89
90
91
92
  }
  
  int ti_lmu_common_set_ramp(struct ti_lmu_bank *lmu_bank)
  {
  	struct regmap *regmap = lmu_bank->regmap;
  	u8 ramp, ramp_up, ramp_down;
  
  	if (lmu_bank->ramp_up_usec == 0 && lmu_bank->ramp_down_usec == 0) {
  		ramp_up = 0;
  		ramp_down = 0;
  	} else {
  		ramp_up = ti_lmu_common_convert_ramp_to_index(lmu_bank->ramp_up_usec);
  		ramp_down = ti_lmu_common_convert_ramp_to_index(lmu_bank->ramp_down_usec);
  	}
3fce8e1eb   Dan Murphy   leds: TI LMU: Add...
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
  	ramp = (ramp_up << 4) | ramp_down;
  
  	return regmap_write(regmap, lmu_bank->runtime_ramp_reg, ramp);
  
  }
  EXPORT_SYMBOL(ti_lmu_common_set_ramp);
  
  int ti_lmu_common_get_ramp_params(struct device *dev,
  				  struct fwnode_handle *child,
  				  struct ti_lmu_bank *lmu_data)
  {
  	int ret;
  
  	ret = fwnode_property_read_u32(child, "ramp-up-us",
  				 &lmu_data->ramp_up_usec);
  	if (ret)
  		dev_warn(dev, "ramp-up-us property missing
  ");
  
  
  	ret = fwnode_property_read_u32(child, "ramp-down-us",
  				 &lmu_data->ramp_down_usec);
  	if (ret)
  		dev_warn(dev, "ramp-down-us property missing
  ");
  
  	return 0;
  }
  EXPORT_SYMBOL(ti_lmu_common_get_ramp_params);
  
  int ti_lmu_common_get_brt_res(struct device *dev, struct fwnode_handle *child,
  				  struct ti_lmu_bank *lmu_data)
  {
  	int ret;
  
  	ret = device_property_read_u32(dev, "ti,brightness-resolution",
  				       &lmu_data->max_brightness);
  	if (ret)
  		ret = fwnode_property_read_u32(child,
  					       "ti,brightness-resolution",
  					       &lmu_data->max_brightness);
  	if (lmu_data->max_brightness <= 0) {
  		lmu_data->max_brightness = MAX_BRIGHTNESS_8BIT;
  		return ret;
  	}
  
  	if (lmu_data->max_brightness > MAX_BRIGHTNESS_11BIT)
  			lmu_data->max_brightness = MAX_BRIGHTNESS_11BIT;
  
  
  	return 0;
  }
  EXPORT_SYMBOL(ti_lmu_common_get_brt_res);
  
  MODULE_DESCRIPTION("TI LMU common LED framework");
  MODULE_AUTHOR("Sebastian Reichel");
  MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");
  MODULE_LICENSE("GPL v2");
  MODULE_ALIAS("ti-lmu-led-common");