stmpe-spi.c (3618B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * ST Microelectronics MFD: stmpe's spi client specific driver 4 * 5 * Copyright (C) ST Microelectronics SA 2011 6 * 7 * Author: Viresh Kumar <vireshk@kernel.org> for ST Microelectronics 8 */ 9 10#include <linux/spi/spi.h> 11#include <linux/interrupt.h> 12#include <linux/kernel.h> 13#include <linux/module.h> 14#include <linux/of.h> 15#include <linux/types.h> 16#include "stmpe.h" 17 18#define READ_CMD (1 << 7) 19 20static int spi_reg_read(struct stmpe *stmpe, u8 reg) 21{ 22 struct spi_device *spi = stmpe->client; 23 int status = spi_w8r16(spi, reg | READ_CMD); 24 25 return (status < 0) ? status : status >> 8; 26} 27 28static int spi_reg_write(struct stmpe *stmpe, u8 reg, u8 val) 29{ 30 struct spi_device *spi = stmpe->client; 31 u16 cmd = (val << 8) | reg; 32 33 return spi_write(spi, (const u8 *)&cmd, 2); 34} 35 36static int spi_block_read(struct stmpe *stmpe, u8 reg, u8 length, u8 *values) 37{ 38 int ret, i; 39 40 for (i = 0; i < length; i++) { 41 ret = spi_reg_read(stmpe, reg + i); 42 if (ret < 0) 43 return ret; 44 *(values + i) = ret; 45 } 46 47 return 0; 48} 49 50static int spi_block_write(struct stmpe *stmpe, u8 reg, u8 length, 51 const u8 *values) 52{ 53 int ret = 0, i; 54 55 for (i = length; i > 0; i--, reg++) { 56 ret = spi_reg_write(stmpe, reg, *(values + i - 1)); 57 if (ret < 0) 58 return ret; 59 } 60 61 return ret; 62} 63 64static void spi_init(struct stmpe *stmpe) 65{ 66 struct spi_device *spi = stmpe->client; 67 68 spi->bits_per_word = 8; 69 70 /* This register is only present for stmpe811 */ 71 if (stmpe->variant->id_val == 0x0811) 72 spi_reg_write(stmpe, STMPE811_REG_SPI_CFG, spi->mode); 73 74 if (spi_setup(spi) < 0) 75 dev_dbg(&spi->dev, "spi_setup failed\n"); 76} 77 78static struct stmpe_client_info spi_ci = { 79 .read_byte = spi_reg_read, 80 .write_byte = spi_reg_write, 81 .read_block = spi_block_read, 82 .write_block = spi_block_write, 83 .init = spi_init, 84}; 85 86static int 87stmpe_spi_probe(struct spi_device *spi) 88{ 89 const struct spi_device_id *id = spi_get_device_id(spi); 90 91 /* don't exceed max specified rate - 1MHz - Limitation of STMPE */ 92 if (spi->max_speed_hz > 1000000) { 93 dev_dbg(&spi->dev, "f(sample) %d KHz?\n", 94 (spi->max_speed_hz/1000)); 95 return -EINVAL; 96 } 97 98 spi_ci.irq = spi->irq; 99 spi_ci.client = spi; 100 spi_ci.dev = &spi->dev; 101 102 return stmpe_probe(&spi_ci, id->driver_data); 103} 104 105static void stmpe_spi_remove(struct spi_device *spi) 106{ 107 struct stmpe *stmpe = spi_get_drvdata(spi); 108 109 stmpe_remove(stmpe); 110} 111 112static const struct of_device_id stmpe_spi_of_match[] = { 113 { .compatible = "st,stmpe610", }, 114 { .compatible = "st,stmpe801", }, 115 { .compatible = "st,stmpe811", }, 116 { .compatible = "st,stmpe1601", }, 117 { .compatible = "st,stmpe2401", }, 118 { .compatible = "st,stmpe2403", }, 119 { /* sentinel */ }, 120}; 121MODULE_DEVICE_TABLE(of, stmpe_spi_of_match); 122 123static const struct spi_device_id stmpe_spi_id[] = { 124 { "stmpe610", STMPE610 }, 125 { "stmpe801", STMPE801 }, 126 { "stmpe811", STMPE811 }, 127 { "stmpe1601", STMPE1601 }, 128 { "stmpe2401", STMPE2401 }, 129 { "stmpe2403", STMPE2403 }, 130 { } 131}; 132MODULE_DEVICE_TABLE(spi, stmpe_id); 133 134static struct spi_driver stmpe_spi_driver = { 135 .driver = { 136 .name = "stmpe-spi", 137 .of_match_table = of_match_ptr(stmpe_spi_of_match), 138#ifdef CONFIG_PM 139 .pm = &stmpe_dev_pm_ops, 140#endif 141 }, 142 .probe = stmpe_spi_probe, 143 .remove = stmpe_spi_remove, 144 .id_table = stmpe_spi_id, 145}; 146 147static int __init stmpe_init(void) 148{ 149 return spi_register_driver(&stmpe_spi_driver); 150} 151subsys_initcall(stmpe_init); 152 153static void __exit stmpe_exit(void) 154{ 155 spi_unregister_driver(&stmpe_spi_driver); 156} 157module_exit(stmpe_exit); 158 159MODULE_LICENSE("GPL v2"); 160MODULE_DESCRIPTION("STMPE MFD SPI Interface Driver"); 161MODULE_AUTHOR("Viresh Kumar <vireshk@kernel.org>");