Blame view

drivers/mfd/stmpe-spi.c 3.55 KB
e789995d5   Viresh Kumar   mfd: Add support ...
1
2
3
4
5
6
  /*
   * ST Microelectronics MFD: stmpe's spi client specific driver
   *
   * Copyright (C) ST Microelectronics SA 2011
   *
   * License Terms: GNU General Public License, version 2
da89947b4   Viresh Kumar   Update Viresh Kum...
7
   * Author: Viresh Kumar <vireshk@kernel.org> for ST Microelectronics
e789995d5   Viresh Kumar   mfd: Add support ...
8
9
10
11
12
13
   */
  
  #include <linux/spi/spi.h>
  #include <linux/interrupt.h>
  #include <linux/kernel.h>
  #include <linux/module.h>
1e955bece   Javier Martinez Canillas   mfd: stmpe: Add O...
14
  #include <linux/of.h>
e789995d5   Viresh Kumar   mfd: Add support ...
15
16
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
  #include <linux/types.h>
  #include "stmpe.h"
  
  #define READ_CMD	(1 << 7)
  
  static int spi_reg_read(struct stmpe *stmpe, u8 reg)
  {
  	struct spi_device *spi = stmpe->client;
  	int status = spi_w8r16(spi, reg | READ_CMD);
  
  	return (status < 0) ? status : status >> 8;
  }
  
  static int spi_reg_write(struct stmpe *stmpe, u8 reg, u8 val)
  {
  	struct spi_device *spi = stmpe->client;
  	u16 cmd = (val << 8) | reg;
  
  	return spi_write(spi, (const u8 *)&cmd, 2);
  }
  
  static int spi_block_read(struct stmpe *stmpe, u8 reg, u8 length, u8 *values)
  {
  	int ret, i;
  
  	for (i = 0; i < length; i++) {
  		ret = spi_reg_read(stmpe, reg + i);
  		if (ret < 0)
  			return ret;
  		*(values + i) = ret;
  	}
  
  	return 0;
  }
  
  static int spi_block_write(struct stmpe *stmpe, u8 reg, u8 length,
  		const u8 *values)
  {
  	int ret = 0, i;
  
  	for (i = length; i > 0; i--, reg++) {
  		ret = spi_reg_write(stmpe, reg, *(values + i - 1));
  		if (ret < 0)
  			return ret;
  	}
  
  	return ret;
  }
  
  static void spi_init(struct stmpe *stmpe)
  {
  	struct spi_device *spi = stmpe->client;
  
  	spi->bits_per_word = 8;
  
  	/* This register is only present for stmpe811 */
  	if (stmpe->variant->id_val == 0x0811)
  		spi_reg_write(stmpe, STMPE811_REG_SPI_CFG, spi->mode);
  
  	if (spi_setup(spi) < 0)
  		dev_dbg(&spi->dev, "spi_setup failed
  ");
  }
  
  static struct stmpe_client_info spi_ci = {
  	.read_byte = spi_reg_read,
  	.write_byte = spi_reg_write,
  	.read_block = spi_block_read,
  	.write_block = spi_block_write,
  	.init = spi_init,
  };
f791be492   Bill Pemberton   mfd: remove use o...
86
  static int
e789995d5   Viresh Kumar   mfd: Add support ...
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
  stmpe_spi_probe(struct spi_device *spi)
  {
  	const struct spi_device_id *id = spi_get_device_id(spi);
  
  	/* don't exceed max specified rate - 1MHz - Limitation of STMPE */
  	if (spi->max_speed_hz > 1000000) {
  		dev_dbg(&spi->dev, "f(sample) %d KHz?
  ",
  				(spi->max_speed_hz/1000));
  		return -EINVAL;
  	}
  
  	spi_ci.irq = spi->irq;
  	spi_ci.client = spi;
  	spi_ci.dev = &spi->dev;
  
  	return stmpe_probe(&spi_ci, id->driver_data);
  }
4740f73fe   Bill Pemberton   mfd: remove use o...
105
  static int stmpe_spi_remove(struct spi_device *spi)
e789995d5   Viresh Kumar   mfd: Add support ...
106
  {
e65ad41e3   Jingoo Han   mfd: stmpe: Use s...
107
  	struct stmpe *stmpe = spi_get_drvdata(spi);
e789995d5   Viresh Kumar   mfd: Add support ...
108
109
110
  
  	return stmpe_remove(stmpe);
  }
1e955bece   Javier Martinez Canillas   mfd: stmpe: Add O...
111
112
113
114
115
116
117
118
119
120
  static const struct of_device_id stmpe_spi_of_match[] = {
  	{ .compatible = "st,stmpe610", },
  	{ .compatible = "st,stmpe801", },
  	{ .compatible = "st,stmpe811", },
  	{ .compatible = "st,stmpe1601", },
  	{ .compatible = "st,stmpe2401", },
  	{ .compatible = "st,stmpe2403", },
  	{ /* sentinel */ },
  };
  MODULE_DEVICE_TABLE(of, stmpe_spi_of_match);
e789995d5   Viresh Kumar   mfd: Add support ...
121
  static const struct spi_device_id stmpe_spi_id[] = {
1cda2394e   Viresh Kumar   mfd: Add support ...
122
  	{ "stmpe610", STMPE610 },
7f7f4ea15   Viresh Kumar   mfd: Add support ...
123
  	{ "stmpe801", STMPE801 },
e789995d5   Viresh Kumar   mfd: Add support ...
124
125
126
127
128
129
130
131
132
133
134
  	{ "stmpe811", STMPE811 },
  	{ "stmpe1601", STMPE1601 },
  	{ "stmpe2401", STMPE2401 },
  	{ "stmpe2403", STMPE2403 },
  	{ }
  };
  MODULE_DEVICE_TABLE(spi, stmpe_id);
  
  static struct spi_driver stmpe_spi_driver = {
  	.driver = {
  		.name	= "stmpe-spi",
1e955bece   Javier Martinez Canillas   mfd: stmpe: Add O...
135
  		.of_match_table = of_match_ptr(stmpe_spi_of_match),
e789995d5   Viresh Kumar   mfd: Add support ...
136
137
138
139
140
  #ifdef CONFIG_PM
  		.pm	= &stmpe_dev_pm_ops,
  #endif
  	},
  	.probe		= stmpe_spi_probe,
84449216b   Bill Pemberton   mfd: remove use o...
141
  	.remove		= stmpe_spi_remove,
e789995d5   Viresh Kumar   mfd: Add support ...
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
  	.id_table	= stmpe_spi_id,
  };
  
  static int __init stmpe_init(void)
  {
  	return spi_register_driver(&stmpe_spi_driver);
  }
  subsys_initcall(stmpe_init);
  
  static void __exit stmpe_exit(void)
  {
  	spi_unregister_driver(&stmpe_spi_driver);
  }
  module_exit(stmpe_exit);
  
  MODULE_LICENSE("GPL v2");
  MODULE_DESCRIPTION("STMPE MFD SPI Interface Driver");
da89947b4   Viresh Kumar   Update Viresh Kum...
159
  MODULE_AUTHOR("Viresh Kumar <vireshk@kernel.org>");