Skip to content

Commit ac2d5b4

Browse files
smaeuldtor
authored andcommitted
Input: sun4i-lradc-keys - add optional clock/reset support
Until the R329, the LRADC hardware was always active. Now it requires enabling a clock gate and deasserting a reset line. Add support for this variant of the hardware. Signed-off-by: Samuel Holland <samuel@sholland.org> Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com> Link: https://lore.kernel.org/r/20220414002349.24332-2-samuel@sholland.org Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
1 parent 61f19f6 commit ac2d5b4

1 file changed

Lines changed: 33 additions & 0 deletions

File tree

drivers/input/keyboard/sun4i-lradc-keys.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
* there are no boards known to use channel 1.
1515
*/
1616

17+
#include <linux/clk.h>
1718
#include <linux/err.h>
1819
#include <linux/init.h>
1920
#include <linux/input.h>
@@ -25,6 +26,7 @@
2526
#include <linux/pm_wakeirq.h>
2627
#include <linux/pm_wakeup.h>
2728
#include <linux/regulator/consumer.h>
29+
#include <linux/reset.h>
2830
#include <linux/slab.h>
2931

3032
#define LRADC_CTRL 0x00
@@ -60,10 +62,12 @@
6062
/* struct lradc_variant - Describe sun4i-a10-lradc-keys hardware variant
6163
* @divisor_numerator: The numerator of lradc Vref internally divisor
6264
* @divisor_denominator: The denominator of lradc Vref internally divisor
65+
* @has_clock_reset: If the binding requires a clock and reset
6366
*/
6467
struct lradc_variant {
6568
u8 divisor_numerator;
6669
u8 divisor_denominator;
70+
bool has_clock_reset;
6771
};
6872

6973
static const struct lradc_variant lradc_variant_a10 = {
@@ -85,6 +89,8 @@ struct sun4i_lradc_data {
8589
struct device *dev;
8690
struct input_dev *input;
8791
void __iomem *base;
92+
struct clk *clk;
93+
struct reset_control *reset;
8894
struct regulator *vref_supply;
8995
struct sun4i_lradc_keymap *chan0_map;
9096
const struct lradc_variant *variant;
@@ -142,6 +148,14 @@ static int sun4i_lradc_open(struct input_dev *dev)
142148
if (error)
143149
return error;
144150

151+
error = reset_control_deassert(lradc->reset);
152+
if (error)
153+
goto err_disable_reg;
154+
155+
error = clk_prepare_enable(lradc->clk);
156+
if (error)
157+
goto err_assert_reset;
158+
145159
lradc->vref = regulator_get_voltage(lradc->vref_supply) *
146160
lradc->variant->divisor_numerator /
147161
lradc->variant->divisor_denominator;
@@ -155,6 +169,13 @@ static int sun4i_lradc_open(struct input_dev *dev)
155169
writel(CHAN0_KEYUP_IRQ | CHAN0_KEYDOWN_IRQ, lradc->base + LRADC_INTC);
156170

157171
return 0;
172+
173+
err_assert_reset:
174+
reset_control_assert(lradc->reset);
175+
err_disable_reg:
176+
regulator_disable(lradc->vref_supply);
177+
178+
return error;
158179
}
159180

160181
static void sun4i_lradc_close(struct input_dev *dev)
@@ -166,6 +187,8 @@ static void sun4i_lradc_close(struct input_dev *dev)
166187
SAMPLE_RATE(2), lradc->base + LRADC_CTRL);
167188
writel(0, lradc->base + LRADC_INTC);
168189

190+
clk_disable_unprepare(lradc->clk);
191+
reset_control_assert(lradc->reset);
169192
regulator_disable(lradc->vref_supply);
170193
}
171194

@@ -244,6 +267,16 @@ static int sun4i_lradc_probe(struct platform_device *pdev)
244267
return -EINVAL;
245268
}
246269

270+
if (lradc->variant->has_clock_reset) {
271+
lradc->clk = devm_clk_get(dev, NULL);
272+
if (IS_ERR(lradc->clk))
273+
return PTR_ERR(lradc->clk);
274+
275+
lradc->reset = devm_reset_control_get_exclusive(dev, NULL);
276+
if (IS_ERR(lradc->reset))
277+
return PTR_ERR(lradc->reset);
278+
}
279+
247280
lradc->vref_supply = devm_regulator_get(dev, "vref");
248281
if (IS_ERR(lradc->vref_supply))
249282
return PTR_ERR(lradc->vref_supply);

0 commit comments

Comments
 (0)