Blame view
drivers/gpio/gpio-max7301.c
2.34 KB
d2912cb15
|
1 |
// SPDX-License-Identifier: GPL-2.0-only |
e952805d2
|
2 |
/* |
0c36ec314
|
3 4 |
* Copyright (C) 2006 Juergen Beisert, Pengutronix * Copyright (C) 2008 Guennadi Liakhovetski, Pengutronix |
e952805d2
|
5 |
* Copyright (C) 2009 Wolfram Sang, Pengutronix |
0c36ec314
|
6 |
* |
e952805d2
|
7 |
* Check max730x.c for further details. |
0c36ec314
|
8 |
*/ |
e952805d2
|
9 |
#include <linux/module.h> |
0c36ec314
|
10 11 12 |
#include <linux/init.h> #include <linux/platform_device.h> #include <linux/mutex.h> |
5a0e3ad6a
|
13 |
#include <linux/slab.h> |
0c36ec314
|
14 15 |
#include <linux/spi/spi.h> #include <linux/spi/max7301.h> |
0c36ec314
|
16 |
|
e952805d2
|
17 18 19 |
/* A write to the MAX7301 means one message with one transfer */ static int max7301_spi_write(struct device *dev, unsigned int reg, unsigned int val) |
0c36ec314
|
20 |
{ |
e952805d2
|
21 |
struct spi_device *spi = to_spi_device(dev); |
0c36ec314
|
22 |
u16 word = ((reg & 0x7F) << 8) | (val & 0xFF); |
e952805d2
|
23 |
|
abf221d2f
|
24 |
return spi_write_then_read(spi, &word, sizeof(word), NULL, 0); |
0c36ec314
|
25 |
} |
e952805d2
|
26 27 28 |
/* A read from the MAX7301 means two transfers; here, one message each */ static int max7301_spi_read(struct device *dev, unsigned int reg) |
0c36ec314
|
29 30 31 |
{ int ret; u16 word; |
e952805d2
|
32 |
struct spi_device *spi = to_spi_device(dev); |
0c36ec314
|
33 34 |
word = 0x8000 | (reg << 8); |
abf221d2f
|
35 36 |
ret = spi_write_then_read(spi, &word, sizeof(word), &word, sizeof(word)); |
0c36ec314
|
37 38 39 40 |
if (ret) return ret; return word & 0xff; } |
3836309d9
|
41 |
static int max7301_probe(struct spi_device *spi) |
0c36ec314
|
42 43 |
{ struct max7301 *ts; |
e952805d2
|
44 |
int ret; |
0c36ec314
|
45 |
|
e952805d2
|
46 |
/* bits_per_word cannot be configured in platform data */ |
31eb4b554
|
47 |
spi->bits_per_word = 16; |
0c36ec314
|
48 49 50 |
ret = spi_setup(spi); if (ret < 0) return ret; |
4cb06cd58
|
51 |
ts = devm_kzalloc(&spi->dev, sizeof(struct max7301), GFP_KERNEL); |
0c36ec314
|
52 53 |
if (!ts) return -ENOMEM; |
e952805d2
|
54 55 56 |
ts->read = max7301_spi_read; ts->write = max7301_spi_write; ts->dev = &spi->dev; |
0c36ec314
|
57 |
|
e952805d2
|
58 |
ret = __max730x_probe(ts); |
0c36ec314
|
59 60 |
return ret; } |
206210ce6
|
61 |
static int max7301_remove(struct spi_device *spi) |
0c36ec314
|
62 |
{ |
e952805d2
|
63 |
return __max730x_remove(&spi->dev); |
0c36ec314
|
64 |
} |
e952805d2
|
65 66 67 68 69 |
static const struct spi_device_id max7301_id[] = { { "max7301", 0 }, { } }; MODULE_DEVICE_TABLE(spi, max7301_id); |
0c36ec314
|
70 71 |
static struct spi_driver max7301_driver = { .driver = { |
e952805d2
|
72 |
.name = "max7301", |
0c36ec314
|
73 |
}, |
e952805d2
|
74 |
.probe = max7301_probe, |
8283c4ff5
|
75 |
.remove = max7301_remove, |
e952805d2
|
76 |
.id_table = max7301_id, |
0c36ec314
|
77 78 79 80 81 82 |
}; static int __init max7301_init(void) { return spi_register_driver(&max7301_driver); } |
673c0c003
|
83 84 85 86 |
/* register after spi postcore initcall and before * subsys initcalls that may rely on these GPIOs */ subsys_initcall(max7301_init); |
0c36ec314
|
87 88 89 90 91 |
static void __exit max7301_exit(void) { spi_unregister_driver(&max7301_driver); } |
0c36ec314
|
92 |
module_exit(max7301_exit); |
e952805d2
|
93 |
MODULE_AUTHOR("Juergen Beisert, Wolfram Sang"); |
0c36ec314
|
94 |
MODULE_LICENSE("GPL v2"); |
e952805d2
|
95 |
MODULE_DESCRIPTION("MAX7301 GPIO-Expander"); |