1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * lm3533-ctrlbank.c -- LM3533 Generic Control Bank interface |
4 | * |
5 | * Copyright (C) 2011-2012 Texas Instruments |
6 | * |
7 | * Author: Johan Hovold <jhovold@gmail.com> |
8 | */ |
9 | |
10 | #include <linux/device.h> |
11 | #include <linux/module.h> |
12 | |
13 | #include <linux/mfd/lm3533.h> |
14 | |
15 | |
16 | #define LM3533_MAX_CURRENT_MIN 5000 |
17 | #define LM3533_MAX_CURRENT_MAX 29800 |
18 | #define LM3533_MAX_CURRENT_STEP 800 |
19 | |
20 | #define LM3533_PWM_MAX 0x3f |
21 | |
22 | #define LM3533_REG_PWM_BASE 0x14 |
23 | #define LM3533_REG_MAX_CURRENT_BASE 0x1f |
24 | #define LM3533_REG_CTRLBANK_ENABLE 0x27 |
25 | #define LM3533_REG_BRIGHTNESS_BASE 0x40 |
26 | |
27 | |
28 | static inline u8 lm3533_ctrlbank_get_reg(struct lm3533_ctrlbank *cb, u8 base) |
29 | { |
30 | return base + cb->id; |
31 | } |
32 | |
33 | int lm3533_ctrlbank_enable(struct lm3533_ctrlbank *cb) |
34 | { |
35 | u8 mask; |
36 | int ret; |
37 | |
38 | dev_dbg(cb->dev, "%s - %d\n" , __func__, cb->id); |
39 | |
40 | mask = 1 << cb->id; |
41 | ret = lm3533_update(lm3533: cb->lm3533, LM3533_REG_CTRLBANK_ENABLE, |
42 | val: mask, mask); |
43 | if (ret) |
44 | dev_err(cb->dev, "failed to enable ctrlbank %d\n" , cb->id); |
45 | |
46 | return ret; |
47 | } |
48 | EXPORT_SYMBOL_GPL(lm3533_ctrlbank_enable); |
49 | |
50 | int lm3533_ctrlbank_disable(struct lm3533_ctrlbank *cb) |
51 | { |
52 | u8 mask; |
53 | int ret; |
54 | |
55 | dev_dbg(cb->dev, "%s - %d\n" , __func__, cb->id); |
56 | |
57 | mask = 1 << cb->id; |
58 | ret = lm3533_update(lm3533: cb->lm3533, LM3533_REG_CTRLBANK_ENABLE, val: 0, mask); |
59 | if (ret) |
60 | dev_err(cb->dev, "failed to disable ctrlbank %d\n" , cb->id); |
61 | |
62 | return ret; |
63 | } |
64 | EXPORT_SYMBOL_GPL(lm3533_ctrlbank_disable); |
65 | |
66 | /* |
67 | * Full-scale current. |
68 | * |
69 | * imax 5000 - 29800 uA (800 uA step) |
70 | */ |
71 | int lm3533_ctrlbank_set_max_current(struct lm3533_ctrlbank *cb, u16 imax) |
72 | { |
73 | u8 reg; |
74 | u8 val; |
75 | int ret; |
76 | |
77 | if (imax < LM3533_MAX_CURRENT_MIN || imax > LM3533_MAX_CURRENT_MAX) |
78 | return -EINVAL; |
79 | |
80 | val = (imax - LM3533_MAX_CURRENT_MIN) / LM3533_MAX_CURRENT_STEP; |
81 | |
82 | reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_MAX_CURRENT_BASE); |
83 | ret = lm3533_write(lm3533: cb->lm3533, reg, val); |
84 | if (ret) |
85 | dev_err(cb->dev, "failed to set max current\n" ); |
86 | |
87 | return ret; |
88 | } |
89 | EXPORT_SYMBOL_GPL(lm3533_ctrlbank_set_max_current); |
90 | |
91 | int lm3533_ctrlbank_set_brightness(struct lm3533_ctrlbank *cb, u8 val) |
92 | { |
93 | u8 reg; |
94 | int ret; |
95 | |
96 | reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_BRIGHTNESS_BASE); |
97 | ret = lm3533_write(lm3533: cb->lm3533, reg, val); |
98 | if (ret) |
99 | dev_err(cb->dev, "failed to set brightness\n" ); |
100 | |
101 | return ret; |
102 | } |
103 | EXPORT_SYMBOL_GPL(lm3533_ctrlbank_set_brightness); |
104 | |
105 | int lm3533_ctrlbank_get_brightness(struct lm3533_ctrlbank *cb, u8 *val) |
106 | { |
107 | u8 reg; |
108 | int ret; |
109 | |
110 | reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_BRIGHTNESS_BASE); |
111 | ret = lm3533_read(lm3533: cb->lm3533, reg, val); |
112 | if (ret) |
113 | dev_err(cb->dev, "failed to get brightness\n" ); |
114 | |
115 | return ret; |
116 | } |
117 | EXPORT_SYMBOL_GPL(lm3533_ctrlbank_get_brightness); |
118 | |
119 | /* |
120 | * PWM-input control mask: |
121 | * |
122 | * bit 5 - PWM-input enabled in Zone 4 |
123 | * bit 4 - PWM-input enabled in Zone 3 |
124 | * bit 3 - PWM-input enabled in Zone 2 |
125 | * bit 2 - PWM-input enabled in Zone 1 |
126 | * bit 1 - PWM-input enabled in Zone 0 |
127 | * bit 0 - PWM-input enabled |
128 | */ |
129 | int lm3533_ctrlbank_set_pwm(struct lm3533_ctrlbank *cb, u8 val) |
130 | { |
131 | u8 reg; |
132 | int ret; |
133 | |
134 | if (val > LM3533_PWM_MAX) |
135 | return -EINVAL; |
136 | |
137 | reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_PWM_BASE); |
138 | ret = lm3533_write(lm3533: cb->lm3533, reg, val); |
139 | if (ret) |
140 | dev_err(cb->dev, "failed to set PWM mask\n" ); |
141 | |
142 | return ret; |
143 | } |
144 | EXPORT_SYMBOL_GPL(lm3533_ctrlbank_set_pwm); |
145 | |
146 | int lm3533_ctrlbank_get_pwm(struct lm3533_ctrlbank *cb, u8 *val) |
147 | { |
148 | u8 reg; |
149 | int ret; |
150 | |
151 | reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_PWM_BASE); |
152 | ret = lm3533_read(lm3533: cb->lm3533, reg, val); |
153 | if (ret) |
154 | dev_err(cb->dev, "failed to get PWM mask\n" ); |
155 | |
156 | return ret; |
157 | } |
158 | EXPORT_SYMBOL_GPL(lm3533_ctrlbank_get_pwm); |
159 | |
160 | MODULE_AUTHOR("Johan Hovold <jhovold@gmail.com>" ); |
161 | MODULE_DESCRIPTION("LM3533 Control Bank interface" ); |
162 | MODULE_LICENSE("GPL" ); |
163 | |