Skip to content

Commit d890cfc

Browse files
linuswalexandrebelloni
authored andcommitted
rtc: ds2404: Convert to GPIO descriptors
This converts the DS2404 to use GPIO descriptors instead of hard-coded global GPIO numbers. The platform data can be deleted because there are no in-tree users and it only contained GPIO numbers which are now passed using descriptor tables (or device tree or ACPI). The driver was rewritten to use a state container for the device driver state (struct ds2404 *chip) and pass that around instead of using a global singleton storage for the GPIO handles. When declaring GPIO descriptor tables or other hardware descriptions for the RTC driver, implementers should take care to flag the RESET line as active low, such as by using the GPIOD_ACTIVE_LOW flag in the descriptor table. Signed-off-by: Linus Walleij <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexandre Belloni <[email protected]>
1 parent 2cf2a1a commit d890cfc

File tree

2 files changed

+69
-120
lines changed

2 files changed

+69
-120
lines changed

drivers/rtc/rtc-ds2404.c

Lines changed: 69 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@
77
#include <linux/rtc.h>
88
#include <linux/types.h>
99
#include <linux/bcd.h>
10-
#include <linux/platform_data/rtc-ds2404.h>
1110
#include <linux/delay.h>
12-
#include <linux/gpio.h>
11+
#include <linux/gpio/consumer.h>
1312
#include <linux/slab.h>
1413

1514
#include <linux/io.h>
@@ -27,164 +26,140 @@
2726
#define DS2404_CLK 1
2827
#define DS2404_DQ 2
2928

30-
struct ds2404_gpio {
31-
const char *name;
32-
unsigned int gpio;
33-
};
34-
3529
struct ds2404 {
36-
struct ds2404_gpio *gpio;
30+
struct device *dev;
31+
struct gpio_desc *rst_gpiod;
32+
struct gpio_desc *clk_gpiod;
33+
struct gpio_desc *dq_gpiod;
3734
struct rtc_device *rtc;
3835
};
3936

40-
static struct ds2404_gpio ds2404_gpio[] = {
41-
{ "RTC RST", 0 },
42-
{ "RTC CLK", 0 },
43-
{ "RTC DQ", 0 },
44-
};
45-
46-
static int ds2404_gpio_map(struct ds2404 *chip, struct platform_device *pdev,
47-
struct ds2404_platform_data *pdata)
37+
static int ds2404_gpio_map(struct ds2404 *chip, struct platform_device *pdev)
4838
{
49-
int i, err;
50-
51-
ds2404_gpio[DS2404_RST].gpio = pdata->gpio_rst;
52-
ds2404_gpio[DS2404_CLK].gpio = pdata->gpio_clk;
53-
ds2404_gpio[DS2404_DQ].gpio = pdata->gpio_dq;
54-
55-
for (i = 0; i < ARRAY_SIZE(ds2404_gpio); i++) {
56-
err = gpio_request(ds2404_gpio[i].gpio, ds2404_gpio[i].name);
57-
if (err) {
58-
dev_err(&pdev->dev, "error mapping gpio %s: %d\n",
59-
ds2404_gpio[i].name, err);
60-
goto err_request;
61-
}
62-
if (i != DS2404_DQ)
63-
gpio_direction_output(ds2404_gpio[i].gpio, 1);
64-
}
39+
struct device *dev = &pdev->dev;
6540

66-
chip->gpio = ds2404_gpio;
67-
return 0;
41+
/* This will de-assert RESET, declare this GPIO as GPIOD_ACTIVE_LOW */
42+
chip->rst_gpiod = devm_gpiod_get(dev, "rst", GPIOD_OUT_LOW);
43+
if (IS_ERR(chip->rst_gpiod))
44+
return PTR_ERR(chip->rst_gpiod);
6845

69-
err_request:
70-
while (--i >= 0)
71-
gpio_free(ds2404_gpio[i].gpio);
72-
return err;
73-
}
46+
chip->clk_gpiod = devm_gpiod_get(dev, "clk", GPIOD_OUT_HIGH);
47+
if (IS_ERR(chip->clk_gpiod))
48+
return PTR_ERR(chip->clk_gpiod);
7449

75-
static void ds2404_gpio_unmap(void *data)
76-
{
77-
int i;
50+
chip->dq_gpiod = devm_gpiod_get(dev, "dq", GPIOD_ASIS);
51+
if (IS_ERR(chip->dq_gpiod))
52+
return PTR_ERR(chip->dq_gpiod);
7853

79-
for (i = 0; i < ARRAY_SIZE(ds2404_gpio); i++)
80-
gpio_free(ds2404_gpio[i].gpio);
54+
return 0;
8155
}
8256

83-
static void ds2404_reset(struct device *dev)
57+
static void ds2404_reset(struct ds2404 *chip)
8458
{
85-
gpio_set_value(ds2404_gpio[DS2404_RST].gpio, 0);
59+
gpiod_set_value(chip->rst_gpiod, 1);
8660
udelay(1000);
87-
gpio_set_value(ds2404_gpio[DS2404_RST].gpio, 1);
88-
gpio_set_value(ds2404_gpio[DS2404_CLK].gpio, 0);
89-
gpio_direction_output(ds2404_gpio[DS2404_DQ].gpio, 0);
61+
gpiod_set_value(chip->rst_gpiod, 0);
62+
gpiod_set_value(chip->clk_gpiod, 0);
63+
gpiod_direction_output(chip->dq_gpiod, 0);
9064
udelay(10);
9165
}
9266

93-
static void ds2404_write_byte(struct device *dev, u8 byte)
67+
static void ds2404_write_byte(struct ds2404 *chip, u8 byte)
9468
{
9569
int i;
9670

97-
gpio_direction_output(ds2404_gpio[DS2404_DQ].gpio, 1);
71+
gpiod_direction_output(chip->dq_gpiod, 1);
9872
for (i = 0; i < 8; i++) {
99-
gpio_set_value(ds2404_gpio[DS2404_DQ].gpio, byte & (1 << i));
73+
gpiod_set_value(chip->dq_gpiod, byte & (1 << i));
10074
udelay(10);
101-
gpio_set_value(ds2404_gpio[DS2404_CLK].gpio, 1);
75+
gpiod_set_value(chip->clk_gpiod, 1);
10276
udelay(10);
103-
gpio_set_value(ds2404_gpio[DS2404_CLK].gpio, 0);
77+
gpiod_set_value(chip->clk_gpiod, 0);
10478
udelay(10);
10579
}
10680
}
10781

108-
static u8 ds2404_read_byte(struct device *dev)
82+
static u8 ds2404_read_byte(struct ds2404 *chip)
10983
{
11084
int i;
11185
u8 ret = 0;
11286

113-
gpio_direction_input(ds2404_gpio[DS2404_DQ].gpio);
87+
gpiod_direction_input(chip->dq_gpiod);
11488

11589
for (i = 0; i < 8; i++) {
116-
gpio_set_value(ds2404_gpio[DS2404_CLK].gpio, 0);
90+
gpiod_set_value(chip->clk_gpiod, 0);
11791
udelay(10);
118-
if (gpio_get_value(ds2404_gpio[DS2404_DQ].gpio))
92+
if (gpiod_get_value(chip->dq_gpiod))
11993
ret |= 1 << i;
120-
gpio_set_value(ds2404_gpio[DS2404_CLK].gpio, 1);
94+
gpiod_set_value(chip->clk_gpiod, 1);
12195
udelay(10);
12296
}
12397
return ret;
12498
}
12599

126-
static void ds2404_read_memory(struct device *dev, u16 offset,
100+
static void ds2404_read_memory(struct ds2404 *chip, u16 offset,
127101
int length, u8 *out)
128102
{
129-
ds2404_reset(dev);
130-
ds2404_write_byte(dev, DS2404_READ_MEMORY_CMD);
131-
ds2404_write_byte(dev, offset & 0xff);
132-
ds2404_write_byte(dev, (offset >> 8) & 0xff);
103+
ds2404_reset(chip);
104+
ds2404_write_byte(chip, DS2404_READ_MEMORY_CMD);
105+
ds2404_write_byte(chip, offset & 0xff);
106+
ds2404_write_byte(chip, (offset >> 8) & 0xff);
133107
while (length--)
134-
*out++ = ds2404_read_byte(dev);
108+
*out++ = ds2404_read_byte(chip);
135109
}
136110

137-
static void ds2404_write_memory(struct device *dev, u16 offset,
111+
static void ds2404_write_memory(struct ds2404 *chip, u16 offset,
138112
int length, u8 *out)
139113
{
140114
int i;
141115
u8 ta01, ta02, es;
142116

143-
ds2404_reset(dev);
144-
ds2404_write_byte(dev, DS2404_WRITE_SCRATCHPAD_CMD);
145-
ds2404_write_byte(dev, offset & 0xff);
146-
ds2404_write_byte(dev, (offset >> 8) & 0xff);
117+
ds2404_reset(chip);
118+
ds2404_write_byte(chip, DS2404_WRITE_SCRATCHPAD_CMD);
119+
ds2404_write_byte(chip, offset & 0xff);
120+
ds2404_write_byte(chip, (offset >> 8) & 0xff);
147121

148122
for (i = 0; i < length; i++)
149-
ds2404_write_byte(dev, out[i]);
123+
ds2404_write_byte(chip, out[i]);
150124

151-
ds2404_reset(dev);
152-
ds2404_write_byte(dev, DS2404_READ_SCRATCHPAD_CMD);
125+
ds2404_reset(chip);
126+
ds2404_write_byte(chip, DS2404_READ_SCRATCHPAD_CMD);
153127

154-
ta01 = ds2404_read_byte(dev);
155-
ta02 = ds2404_read_byte(dev);
156-
es = ds2404_read_byte(dev);
128+
ta01 = ds2404_read_byte(chip);
129+
ta02 = ds2404_read_byte(chip);
130+
es = ds2404_read_byte(chip);
157131

158132
for (i = 0; i < length; i++) {
159-
if (out[i] != ds2404_read_byte(dev)) {
160-
dev_err(dev, "read invalid data\n");
133+
if (out[i] != ds2404_read_byte(chip)) {
134+
dev_err(chip->dev, "read invalid data\n");
161135
return;
162136
}
163137
}
164138

165-
ds2404_reset(dev);
166-
ds2404_write_byte(dev, DS2404_COPY_SCRATCHPAD_CMD);
167-
ds2404_write_byte(dev, ta01);
168-
ds2404_write_byte(dev, ta02);
169-
ds2404_write_byte(dev, es);
139+
ds2404_reset(chip);
140+
ds2404_write_byte(chip, DS2404_COPY_SCRATCHPAD_CMD);
141+
ds2404_write_byte(chip, ta01);
142+
ds2404_write_byte(chip, ta02);
143+
ds2404_write_byte(chip, es);
170144

171-
gpio_direction_input(ds2404_gpio[DS2404_DQ].gpio);
172-
while (gpio_get_value(ds2404_gpio[DS2404_DQ].gpio))
145+
while (gpiod_get_value(chip->dq_gpiod))
173146
;
174147
}
175148

176-
static void ds2404_enable_osc(struct device *dev)
149+
static void ds2404_enable_osc(struct ds2404 *chip)
177150
{
178151
u8 in[1] = { 0x10 }; /* enable oscillator */
179-
ds2404_write_memory(dev, 0x201, 1, in);
152+
153+
ds2404_write_memory(chip, 0x201, 1, in);
180154
}
181155

182156
static int ds2404_read_time(struct device *dev, struct rtc_time *dt)
183157
{
158+
struct ds2404 *chip = dev_get_drvdata(dev);
184159
unsigned long time = 0;
185160
__le32 hw_time = 0;
186161

187-
ds2404_read_memory(dev, 0x203, 4, (u8 *)&hw_time);
162+
ds2404_read_memory(chip, 0x203, 4, (u8 *)&hw_time);
188163
time = le32_to_cpu(hw_time);
189164

190165
rtc_time64_to_tm(time, dt);
@@ -193,8 +168,9 @@ static int ds2404_read_time(struct device *dev, struct rtc_time *dt)
193168

194169
static int ds2404_set_time(struct device *dev, struct rtc_time *dt)
195170
{
171+
struct ds2404 *chip = dev_get_drvdata(dev);
196172
u32 time = cpu_to_le32(rtc_tm_to_time64(dt));
197-
ds2404_write_memory(dev, 0x203, 4, (u8 *)&time);
173+
ds2404_write_memory(chip, 0x203, 4, (u8 *)&time);
198174
return 0;
199175
}
200176

@@ -205,30 +181,23 @@ static const struct rtc_class_ops ds2404_rtc_ops = {
205181

206182
static int rtc_probe(struct platform_device *pdev)
207183
{
208-
struct ds2404_platform_data *pdata = dev_get_platdata(&pdev->dev);
209184
struct ds2404 *chip;
210185
int retval = -EBUSY;
211186

212187
chip = devm_kzalloc(&pdev->dev, sizeof(struct ds2404), GFP_KERNEL);
213188
if (!chip)
214189
return -ENOMEM;
215190

191+
chip->dev = &pdev->dev;
192+
216193
chip->rtc = devm_rtc_allocate_device(&pdev->dev);
217194
if (IS_ERR(chip->rtc))
218195
return PTR_ERR(chip->rtc);
219196

220-
retval = ds2404_gpio_map(chip, pdev, pdata);
197+
retval = ds2404_gpio_map(chip, pdev);
221198
if (retval)
222199
return retval;
223200

224-
retval = devm_add_action_or_reset(&pdev->dev, ds2404_gpio_unmap, chip);
225-
if (retval)
226-
return retval;
227-
228-
dev_info(&pdev->dev, "using GPIOs RST:%d, CLK:%d, DQ:%d\n",
229-
chip->gpio[DS2404_RST].gpio, chip->gpio[DS2404_CLK].gpio,
230-
chip->gpio[DS2404_DQ].gpio);
231-
232201
platform_set_drvdata(pdev, chip);
233202

234203
chip->rtc->ops = &ds2404_rtc_ops;
@@ -238,7 +207,7 @@ static int rtc_probe(struct platform_device *pdev)
238207
if (retval)
239208
return retval;
240209

241-
ds2404_enable_osc(&pdev->dev);
210+
ds2404_enable_osc(chip);
242211
return 0;
243212
}
244213

include/linux/platform_data/rtc-ds2404.h

Lines changed: 0 additions & 20 deletions
This file was deleted.

0 commit comments

Comments
 (0)