115fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell/* 2c103de240439dfee24ac50eb99c8be3a30d13323Grant Likely * Driver for pcf857x, pca857x, and pca967x I2C GPIO expanders 315fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * 415fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * Copyright (C) 2007 David Brownell 515fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * 615fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * This program is free software; you can redistribute it and/or modify 715fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * it under the terms of the GNU General Public License as published by 815fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * the Free Software Foundation; either version 2 of the License, or 915fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * (at your option) any later version. 1015fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * 1115fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * This program is distributed in the hope that it will be useful, 1215fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * but WITHOUT ANY WARRANTY; without even the implied warranty of 1315fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1415fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * GNU General Public License for more details. 1515fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * 1615fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * You should have received a copy of the GNU General Public License 1715fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * along with this program; if not, write to the Free Software 1815fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 1915fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell */ 2015fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 21d120c17faeb391f5b4b99af8b1e190619934ecddH Hartley Sweeten#include <linux/gpio.h> 2215fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell#include <linux/i2c.h> 2315fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell#include <linux/i2c/pcf857x.h> 246e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto#include <linux/interrupt.h> 256e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto#include <linux/irq.h> 266e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto#include <linux/irqdomain.h> 27c990d6cb3bdb3132c7ceddfc94eb25096d95d58cLaurent Pinchart#include <linux/kernel.h> 28bb207ef1e84ffc4afe89f3a5b84788bac0f968e7Paul Gortmaker#include <linux/module.h> 2963f57cd45b0811de9663edf4af6b170c5bd3860dLaurent Pinchart#include <linux/of.h> 3063f57cd45b0811de9663edf4af6b170c5bd3860dLaurent Pinchart#include <linux/of_device.h> 31c990d6cb3bdb3132c7ceddfc94eb25096d95d58cLaurent Pinchart#include <linux/slab.h> 326e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto#include <linux/spinlock.h> 3315fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 3415fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 353760f736716f74bdc62a4ba5406934338da93eb2Jean Delvarestatic const struct i2c_device_id pcf857x_id[] = { 363760f736716f74bdc62a4ba5406934338da93eb2Jean Delvare { "pcf8574", 8 }, 374ba2ccb83e03077bb94f8848ee573f1e27cea969Wolfram Sang { "pcf8574a", 8 }, 383760f736716f74bdc62a4ba5406934338da93eb2Jean Delvare { "pca8574", 8 }, 393760f736716f74bdc62a4ba5406934338da93eb2Jean Delvare { "pca9670", 8 }, 403760f736716f74bdc62a4ba5406934338da93eb2Jean Delvare { "pca9672", 8 }, 413760f736716f74bdc62a4ba5406934338da93eb2Jean Delvare { "pca9674", 8 }, 423760f736716f74bdc62a4ba5406934338da93eb2Jean Delvare { "pcf8575", 16 }, 433760f736716f74bdc62a4ba5406934338da93eb2Jean Delvare { "pca8575", 16 }, 443760f736716f74bdc62a4ba5406934338da93eb2Jean Delvare { "pca9671", 16 }, 453760f736716f74bdc62a4ba5406934338da93eb2Jean Delvare { "pca9673", 16 }, 463760f736716f74bdc62a4ba5406934338da93eb2Jean Delvare { "pca9675", 16 }, 471673ad52bd9a3c747e596a76e65c55981ea651e3David Brownell { "max7328", 8 }, 481673ad52bd9a3c747e596a76e65c55981ea651e3David Brownell { "max7329", 8 }, 49021304907bd06a92cee362c605bd4d9a83bb1927Nikolay Balandin { "tca9554", 8 }, 503760f736716f74bdc62a4ba5406934338da93eb2Jean Delvare { } 513760f736716f74bdc62a4ba5406934338da93eb2Jean Delvare}; 523760f736716f74bdc62a4ba5406934338da93eb2Jean DelvareMODULE_DEVICE_TABLE(i2c, pcf857x_id); 533760f736716f74bdc62a4ba5406934338da93eb2Jean Delvare 5463f57cd45b0811de9663edf4af6b170c5bd3860dLaurent Pinchart#ifdef CONFIG_OF 5563f57cd45b0811de9663edf4af6b170c5bd3860dLaurent Pinchartstatic const struct of_device_id pcf857x_of_table[] = { 5663f57cd45b0811de9663edf4af6b170c5bd3860dLaurent Pinchart { .compatible = "nxp,pcf8574" }, 5763f57cd45b0811de9663edf4af6b170c5bd3860dLaurent Pinchart { .compatible = "nxp,pcf8574a" }, 5863f57cd45b0811de9663edf4af6b170c5bd3860dLaurent Pinchart { .compatible = "nxp,pca8574" }, 5963f57cd45b0811de9663edf4af6b170c5bd3860dLaurent Pinchart { .compatible = "nxp,pca9670" }, 6063f57cd45b0811de9663edf4af6b170c5bd3860dLaurent Pinchart { .compatible = "nxp,pca9672" }, 6163f57cd45b0811de9663edf4af6b170c5bd3860dLaurent Pinchart { .compatible = "nxp,pca9674" }, 6263f57cd45b0811de9663edf4af6b170c5bd3860dLaurent Pinchart { .compatible = "nxp,pcf8575" }, 6363f57cd45b0811de9663edf4af6b170c5bd3860dLaurent Pinchart { .compatible = "nxp,pca8575" }, 6463f57cd45b0811de9663edf4af6b170c5bd3860dLaurent Pinchart { .compatible = "nxp,pca9671" }, 6563f57cd45b0811de9663edf4af6b170c5bd3860dLaurent Pinchart { .compatible = "nxp,pca9673" }, 6663f57cd45b0811de9663edf4af6b170c5bd3860dLaurent Pinchart { .compatible = "nxp,pca9675" }, 6763f57cd45b0811de9663edf4af6b170c5bd3860dLaurent Pinchart { .compatible = "maxim,max7328" }, 6863f57cd45b0811de9663edf4af6b170c5bd3860dLaurent Pinchart { .compatible = "maxim,max7329" }, 6963f57cd45b0811de9663edf4af6b170c5bd3860dLaurent Pinchart { .compatible = "ti,tca9554" }, 7063f57cd45b0811de9663edf4af6b170c5bd3860dLaurent Pinchart { } 7163f57cd45b0811de9663edf4af6b170c5bd3860dLaurent Pinchart}; 7263f57cd45b0811de9663edf4af6b170c5bd3860dLaurent PinchartMODULE_DEVICE_TABLE(of, pcf857x_of_table); 7363f57cd45b0811de9663edf4af6b170c5bd3860dLaurent Pinchart#endif 7463f57cd45b0811de9663edf4af6b170c5bd3860dLaurent Pinchart 7515fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell/* 7615fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * The pcf857x, pca857x, and pca967x chips only expose one read and one 7715fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * write register. Writing a "one" bit (to match the reset state) lets 7815fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * that pin be used as an input; it's not an open-drain model, but acts 7915fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * a bit like one. This is described as "quasi-bidirectional"; read the 8015fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * chip documentation for details. 8115fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * 8215fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * Many other I2C GPIO expander chips (like the pca953x models) have 8315fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * more complex register models and more conventional circuitry using 8415fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * push/pull drivers. They often use the same 0x20..0x27 addresses as 8515fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * pcf857x parts, making the "legacy" I2C driver model problematic. 8615fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell */ 8715fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownellstruct pcf857x { 8815fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell struct gpio_chip chip; 8915fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell struct i2c_client *client; 901673ad52bd9a3c747e596a76e65c55981ea651e3David Brownell struct mutex lock; /* protect 'out' */ 916e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto struct irq_domain *irq_domain; /* for irq demux */ 926e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto spinlock_t slock; /* protect irq demux */ 9315fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell unsigned out; /* software latch */ 946e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto unsigned status; /* current status */ 9521fd3cd1874a2ac85990b981a8ab449e9e4ef5b9George Cherian unsigned irq_mapped; /* mapped gpio irqs */ 960c65ddd460086084079eeeb14d062c9a0c437ca0Kuninori Morimoto 970c65ddd460086084079eeeb14d062c9a0c437ca0Kuninori Morimoto int (*write)(struct i2c_client *client, unsigned data); 980c65ddd460086084079eeeb14d062c9a0c437ca0Kuninori Morimoto int (*read)(struct i2c_client *client); 9915fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell}; 10015fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 10115fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell/*-------------------------------------------------------------------------*/ 10215fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 10315fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell/* Talk to 8-bit I/O expander */ 10415fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 1050c65ddd460086084079eeeb14d062c9a0c437ca0Kuninori Morimotostatic int i2c_write_le8(struct i2c_client *client, unsigned data) 10615fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell{ 1070c65ddd460086084079eeeb14d062c9a0c437ca0Kuninori Morimoto return i2c_smbus_write_byte(client, data); 10815fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell} 10915fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 1100c65ddd460086084079eeeb14d062c9a0c437ca0Kuninori Morimotostatic int i2c_read_le8(struct i2c_client *client) 11115fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell{ 1120c65ddd460086084079eeeb14d062c9a0c437ca0Kuninori Morimoto return (int)i2c_smbus_read_byte(client); 11315fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell} 11415fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 11515fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell/* Talk to 16-bit I/O expander */ 11615fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 1170c65ddd460086084079eeeb14d062c9a0c437ca0Kuninori Morimotostatic int i2c_write_le16(struct i2c_client *client, unsigned word) 11815fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell{ 11915fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell u8 buf[2] = { word & 0xff, word >> 8, }; 12015fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell int status; 12115fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 12215fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell status = i2c_master_send(client, buf, 2); 12315fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell return (status < 0) ? status : 0; 12415fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell} 12515fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 12615fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownellstatic int i2c_read_le16(struct i2c_client *client) 12715fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell{ 12815fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell u8 buf[2]; 12915fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell int status; 13015fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 13115fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell status = i2c_master_recv(client, buf, 2); 13215fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell if (status < 0) 13315fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell return status; 13415fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell return (buf[1] << 8) | buf[0]; 13515fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell} 13615fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 1370c65ddd460086084079eeeb14d062c9a0c437ca0Kuninori Morimoto/*-------------------------------------------------------------------------*/ 1380c65ddd460086084079eeeb14d062c9a0c437ca0Kuninori Morimoto 1390c65ddd460086084079eeeb14d062c9a0c437ca0Kuninori Morimotostatic int pcf857x_input(struct gpio_chip *chip, unsigned offset) 14015fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell{ 14115fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); 1421673ad52bd9a3c747e596a76e65c55981ea651e3David Brownell int status; 14315fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 1441673ad52bd9a3c747e596a76e65c55981ea651e3David Brownell mutex_lock(&gpio->lock); 14515fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell gpio->out |= (1 << offset); 1460c65ddd460086084079eeeb14d062c9a0c437ca0Kuninori Morimoto status = gpio->write(gpio->client, gpio->out); 1471673ad52bd9a3c747e596a76e65c55981ea651e3David Brownell mutex_unlock(&gpio->lock); 1481673ad52bd9a3c747e596a76e65c55981ea651e3David Brownell 1491673ad52bd9a3c747e596a76e65c55981ea651e3David Brownell return status; 15015fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell} 15115fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 1520c65ddd460086084079eeeb14d062c9a0c437ca0Kuninori Morimotostatic int pcf857x_get(struct gpio_chip *chip, unsigned offset) 15315fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell{ 15415fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); 15515fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell int value; 15615fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 1570c65ddd460086084079eeeb14d062c9a0c437ca0Kuninori Morimoto value = gpio->read(gpio->client); 15815fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell return (value < 0) ? 0 : (value & (1 << offset)); 15915fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell} 16015fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 1610c65ddd460086084079eeeb14d062c9a0c437ca0Kuninori Morimotostatic int pcf857x_output(struct gpio_chip *chip, unsigned offset, int value) 16215fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell{ 16315fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); 16415fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell unsigned bit = 1 << offset; 1651673ad52bd9a3c747e596a76e65c55981ea651e3David Brownell int status; 16615fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 1671673ad52bd9a3c747e596a76e65c55981ea651e3David Brownell mutex_lock(&gpio->lock); 16815fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell if (value) 16915fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell gpio->out |= bit; 17015fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell else 17115fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell gpio->out &= ~bit; 1720c65ddd460086084079eeeb14d062c9a0c437ca0Kuninori Morimoto status = gpio->write(gpio->client, gpio->out); 1731673ad52bd9a3c747e596a76e65c55981ea651e3David Brownell mutex_unlock(&gpio->lock); 1741673ad52bd9a3c747e596a76e65c55981ea651e3David Brownell 1751673ad52bd9a3c747e596a76e65c55981ea651e3David Brownell return status; 17615fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell} 17715fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 1780c65ddd460086084079eeeb14d062c9a0c437ca0Kuninori Morimotostatic void pcf857x_set(struct gpio_chip *chip, unsigned offset, int value) 17915fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell{ 1800c65ddd460086084079eeeb14d062c9a0c437ca0Kuninori Morimoto pcf857x_output(chip, offset, value); 18115fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell} 18215fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 18315fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell/*-------------------------------------------------------------------------*/ 18415fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 1856e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimotostatic int pcf857x_to_irq(struct gpio_chip *chip, unsigned offset) 1866e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto{ 1876e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); 18821fd3cd1874a2ac85990b981a8ab449e9e4ef5b9George Cherian int ret; 1896e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto 19021fd3cd1874a2ac85990b981a8ab449e9e4ef5b9George Cherian ret = irq_create_mapping(gpio->irq_domain, offset); 19121fd3cd1874a2ac85990b981a8ab449e9e4ef5b9George Cherian if (ret > 0) 19221fd3cd1874a2ac85990b981a8ab449e9e4ef5b9George Cherian gpio->irq_mapped |= (1 << offset); 19321fd3cd1874a2ac85990b981a8ab449e9e4ef5b9George Cherian 19421fd3cd1874a2ac85990b981a8ab449e9e4ef5b9George Cherian return ret; 1956e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto} 1966e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto 1975c21d008713918bcc4289e6ccb327b17b35dc4efGeorge Cherianstatic irqreturn_t pcf857x_irq(int irq, void *data) 1985c21d008713918bcc4289e6ccb327b17b35dc4efGeorge Cherian{ 1995c21d008713918bcc4289e6ccb327b17b35dc4efGeorge Cherian struct pcf857x *gpio = data; 2005c21d008713918bcc4289e6ccb327b17b35dc4efGeorge Cherian unsigned long change, i, status, flags; 2015c21d008713918bcc4289e6ccb327b17b35dc4efGeorge Cherian 2025c21d008713918bcc4289e6ccb327b17b35dc4efGeorge Cherian status = gpio->read(gpio->client); 2035c21d008713918bcc4289e6ccb327b17b35dc4efGeorge Cherian 2045c21d008713918bcc4289e6ccb327b17b35dc4efGeorge Cherian spin_lock_irqsave(&gpio->slock, flags); 2055c21d008713918bcc4289e6ccb327b17b35dc4efGeorge Cherian 20621fd3cd1874a2ac85990b981a8ab449e9e4ef5b9George Cherian /* 20721fd3cd1874a2ac85990b981a8ab449e9e4ef5b9George Cherian * call the interrupt handler iff gpio is used as 20821fd3cd1874a2ac85990b981a8ab449e9e4ef5b9George Cherian * interrupt source, just to avoid bad irqs 20921fd3cd1874a2ac85990b981a8ab449e9e4ef5b9George Cherian */ 21021fd3cd1874a2ac85990b981a8ab449e9e4ef5b9George Cherian 21121fd3cd1874a2ac85990b981a8ab449e9e4ef5b9George Cherian change = ((gpio->status ^ status) & gpio->irq_mapped); 2125c21d008713918bcc4289e6ccb327b17b35dc4efGeorge Cherian for_each_set_bit(i, &change, gpio->chip.ngpio) 2135c21d008713918bcc4289e6ccb327b17b35dc4efGeorge Cherian generic_handle_irq(irq_find_mapping(gpio->irq_domain, i)); 2145c21d008713918bcc4289e6ccb327b17b35dc4efGeorge Cherian gpio->status = status; 2155c21d008713918bcc4289e6ccb327b17b35dc4efGeorge Cherian 2165c21d008713918bcc4289e6ccb327b17b35dc4efGeorge Cherian spin_unlock_irqrestore(&gpio->slock, flags); 2175c21d008713918bcc4289e6ccb327b17b35dc4efGeorge Cherian 2185c21d008713918bcc4289e6ccb327b17b35dc4efGeorge Cherian return IRQ_HANDLED; 2195c21d008713918bcc4289e6ccb327b17b35dc4efGeorge Cherian} 2205c21d008713918bcc4289e6ccb327b17b35dc4efGeorge Cherian 221c27769ef6e118d355922d9c4a530b9d68405b39bLinus Walleijstatic int pcf857x_irq_domain_map(struct irq_domain *domain, unsigned int irq, 2226e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto irq_hw_number_t hw) 2236e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto{ 22421fd3cd1874a2ac85990b981a8ab449e9e4ef5b9George Cherian struct pcf857x *gpio = domain->host_data; 22521fd3cd1874a2ac85990b981a8ab449e9e4ef5b9George Cherian 226c27769ef6e118d355922d9c4a530b9d68405b39bLinus Walleij irq_set_chip_and_handler(irq, 2276e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto &dummy_irq_chip, 2286e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto handle_level_irq); 229c27769ef6e118d355922d9c4a530b9d68405b39bLinus Walleij#ifdef CONFIG_ARM 230c27769ef6e118d355922d9c4a530b9d68405b39bLinus Walleij set_irq_flags(irq, IRQF_VALID); 231c27769ef6e118d355922d9c4a530b9d68405b39bLinus Walleij#else 232c27769ef6e118d355922d9c4a530b9d68405b39bLinus Walleij irq_set_noprobe(irq); 233c27769ef6e118d355922d9c4a530b9d68405b39bLinus Walleij#endif 23421fd3cd1874a2ac85990b981a8ab449e9e4ef5b9George Cherian gpio->irq_mapped |= (1 << hw); 23521fd3cd1874a2ac85990b981a8ab449e9e4ef5b9George Cherian 2366e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto return 0; 2376e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto} 2386e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto 2396e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimotostatic struct irq_domain_ops pcf857x_irq_domain_ops = { 2406e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto .map = pcf857x_irq_domain_map, 2416e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto}; 2426e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto 2436e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimotostatic void pcf857x_irq_domain_cleanup(struct pcf857x *gpio) 2446e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto{ 2456e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto if (gpio->irq_domain) 2466e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto irq_domain_remove(gpio->irq_domain); 2476e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto 2486e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto} 2496e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto 2506e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimotostatic int pcf857x_irq_domain_init(struct pcf857x *gpio, 251805f864ebefc39065b6b0cf2548f13c2fbf888d9Kuninori Morimoto struct i2c_client *client) 2526e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto{ 2536e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto int status; 2546e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto 255805f864ebefc39065b6b0cf2548f13c2fbf888d9Kuninori Morimoto gpio->irq_domain = irq_domain_add_linear(client->dev.of_node, 2566e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto gpio->chip.ngpio, 2576e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto &pcf857x_irq_domain_ops, 25821fd3cd1874a2ac85990b981a8ab449e9e4ef5b9George Cherian gpio); 2596e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto if (!gpio->irq_domain) 2606e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto goto fail; 2616e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto 2626e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto /* enable real irq */ 2635c21d008713918bcc4289e6ccb327b17b35dc4efGeorge Cherian status = devm_request_threaded_irq(&client->dev, client->irq, 2645c21d008713918bcc4289e6ccb327b17b35dc4efGeorge Cherian NULL, pcf857x_irq, IRQF_ONESHOT | 2655795cf35030bfa180a6f5c948681821f7019fc18George Cherian IRQF_TRIGGER_FALLING | IRQF_SHARED, 2665c21d008713918bcc4289e6ccb327b17b35dc4efGeorge Cherian dev_name(&client->dev), gpio); 2675c21d008713918bcc4289e6ccb327b17b35dc4efGeorge Cherian 2686e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto if (status) 2696e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto goto fail; 2706e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto 2716e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto /* enable gpio_to_irq() */ 2726e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto gpio->chip.to_irq = pcf857x_to_irq; 2736e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto 2746e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto return 0; 2756e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto 2766e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimotofail: 2776e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto pcf857x_irq_domain_cleanup(gpio); 2786e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto return -EINVAL; 2796e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto} 2806e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto 2816e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto/*-------------------------------------------------------------------------*/ 2826e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto 283d2653e92732bd3911feff6bee5e23dbf959381dbJean Delvarestatic int pcf857x_probe(struct i2c_client *client, 284d2653e92732bd3911feff6bee5e23dbf959381dbJean Delvare const struct i2c_device_id *id) 28515fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell{ 28663f57cd45b0811de9663edf4af6b170c5bd3860dLaurent Pinchart struct pcf857x_platform_data *pdata = dev_get_platdata(&client->dev); 28763f57cd45b0811de9663edf4af6b170c5bd3860dLaurent Pinchart struct device_node *np = client->dev.of_node; 28815fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell struct pcf857x *gpio; 28963f57cd45b0811de9663edf4af6b170c5bd3860dLaurent Pinchart unsigned int n_latch = 0; 29015fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell int status; 29115fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 29263f57cd45b0811de9663edf4af6b170c5bd3860dLaurent Pinchart if (IS_ENABLED(CONFIG_OF) && np) 29363f57cd45b0811de9663edf4af6b170c5bd3860dLaurent Pinchart of_property_read_u32(np, "lines-initial-states", &n_latch); 29463f57cd45b0811de9663edf4af6b170c5bd3860dLaurent Pinchart else if (pdata) 29563f57cd45b0811de9663edf4af6b170c5bd3860dLaurent Pinchart n_latch = pdata->n_latch; 29663f57cd45b0811de9663edf4af6b170c5bd3860dLaurent Pinchart else 297a342d215c206d955fea55d778e3803b29ee41b60Ben Dooks dev_dbg(&client->dev, "no platform data\n"); 29815fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 29915fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell /* Allocate, initialize, and register this gpio_chip. */ 300f39f54af032ce900815d0d718df5f1717eed50feJingoo Han gpio = devm_kzalloc(&client->dev, sizeof(*gpio), GFP_KERNEL); 30115fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell if (!gpio) 30215fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell return -ENOMEM; 30315fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 3041673ad52bd9a3c747e596a76e65c55981ea651e3David Brownell mutex_init(&gpio->lock); 3056e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto spin_lock_init(&gpio->slock); 3061673ad52bd9a3c747e596a76e65c55981ea651e3David Brownell 3070c65ddd460086084079eeeb14d062c9a0c437ca0Kuninori Morimoto gpio->chip.base = pdata ? pdata->gpio_base : -1; 3089fb1f39eb2d6707d265087ee186376e24995f55aLinus Walleij gpio->chip.can_sleep = true; 3090c65ddd460086084079eeeb14d062c9a0c437ca0Kuninori Morimoto gpio->chip.dev = &client->dev; 3100c65ddd460086084079eeeb14d062c9a0c437ca0Kuninori Morimoto gpio->chip.owner = THIS_MODULE; 3110c65ddd460086084079eeeb14d062c9a0c437ca0Kuninori Morimoto gpio->chip.get = pcf857x_get; 3120c65ddd460086084079eeeb14d062c9a0c437ca0Kuninori Morimoto gpio->chip.set = pcf857x_set; 3130c65ddd460086084079eeeb14d062c9a0c437ca0Kuninori Morimoto gpio->chip.direction_input = pcf857x_input; 3140c65ddd460086084079eeeb14d062c9a0c437ca0Kuninori Morimoto gpio->chip.direction_output = pcf857x_output; 3150c65ddd460086084079eeeb14d062c9a0c437ca0Kuninori Morimoto gpio->chip.ngpio = id->driver_data; 31615fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 3176e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto /* enable gpio_to_irq() if platform has settings */ 318655c4e79370d1731c293c47aaf85d4c990a33052Laurent Pinchart if (client->irq) { 319655c4e79370d1731c293c47aaf85d4c990a33052Laurent Pinchart status = pcf857x_irq_domain_init(gpio, client); 3206e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto if (status < 0) { 3216e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto dev_err(&client->dev, "irq_domain init failed\n"); 322e6b698f69adce0119b5f5ed00789d1a0e0af975fGeorge Cherian goto fail_irq_domain; 3236e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto } 3246e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto } 3256e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto 32615fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell /* NOTE: the OnSemi jlc1562b is also largely compatible with 32715fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * these parts, notably for output. It has a low-resolution 32815fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * DAC instead of pin change IRQs; and its inputs can be the 32915fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * result of comparators. 33015fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell */ 33115fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 33215fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell /* 8574 addresses are 0x20..0x27; 8574a uses 0x38..0x3f; 33315fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * 9670, 9672, 9764, and 9764a use quite a variety. 33415fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * 33515fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * NOTE: we don't distinguish here between *4 and *4a parts. 33615fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell */ 3373760f736716f74bdc62a4ba5406934338da93eb2Jean Delvare if (gpio->chip.ngpio == 8) { 3380c65ddd460086084079eeeb14d062c9a0c437ca0Kuninori Morimoto gpio->write = i2c_write_le8; 3390c65ddd460086084079eeeb14d062c9a0c437ca0Kuninori Morimoto gpio->read = i2c_read_le8; 34015fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 34115fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell if (!i2c_check_functionality(client->adapter, 34215fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell I2C_FUNC_SMBUS_BYTE)) 34315fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell status = -EIO; 34415fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 34515fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell /* fail if there's no chip present */ 34615fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell else 34715fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell status = i2c_smbus_read_byte(client); 34815fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 34915fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell /* '75/'75c addresses are 0x20..0x27, just like the '74; 35015fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * the '75c doesn't have a current source pulling high. 35115fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * 9671, 9673, and 9765 use quite a variety of addresses. 35215fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * 35315fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * NOTE: we don't distinguish here between '75 and '75c parts. 35415fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell */ 3553760f736716f74bdc62a4ba5406934338da93eb2Jean Delvare } else if (gpio->chip.ngpio == 16) { 3560c65ddd460086084079eeeb14d062c9a0c437ca0Kuninori Morimoto gpio->write = i2c_write_le16; 3570c65ddd460086084079eeeb14d062c9a0c437ca0Kuninori Morimoto gpio->read = i2c_read_le16; 35815fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 35915fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) 36015fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell status = -EIO; 36115fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 36215fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell /* fail if there's no chip present */ 36315fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell else 36415fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell status = i2c_read_le16(client); 36515fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 366a342d215c206d955fea55d778e3803b29ee41b60Ben Dooks } else { 367a342d215c206d955fea55d778e3803b29ee41b60Ben Dooks dev_dbg(&client->dev, "unsupported number of gpios\n"); 368a342d215c206d955fea55d778e3803b29ee41b60Ben Dooks status = -EINVAL; 369a342d215c206d955fea55d778e3803b29ee41b60Ben Dooks } 37015fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 37115fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell if (status < 0) 37215fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell goto fail; 37315fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 37415fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell gpio->chip.label = client->name; 37515fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 37615fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell gpio->client = client; 37715fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell i2c_set_clientdata(client, gpio); 37815fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 37915fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell /* NOTE: these chips have strange "quasi-bidirectional" I/O pins. 38015fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * We can't actually know whether a pin is configured (a) as output 38115fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * and driving the signal low, or (b) as input and reporting a low 38215fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * value ... without knowing the last value written since the chip 38315fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * came out of reset (if any). We can't read the latched output. 38415fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * 38515fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * In short, the only reliable solution for setting up pin direction 38615fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * is to do it explicitly. The setup() method can do that, but it 38715fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * may cause transient glitching since it can't know the last value 38815fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * written (some pins may need to be driven low). 38915fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * 39063f57cd45b0811de9663edf4af6b170c5bd3860dLaurent Pinchart * Using n_latch avoids that trouble. When left initialized to zero, 39163f57cd45b0811de9663edf4af6b170c5bd3860dLaurent Pinchart * our software copy of the "latch" then matches the chip's all-ones 39263f57cd45b0811de9663edf4af6b170c5bd3860dLaurent Pinchart * reset state. Otherwise it flags pins to be driven low. 39315fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell */ 39463f57cd45b0811de9663edf4af6b170c5bd3860dLaurent Pinchart gpio->out = ~n_latch; 3956e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto gpio->status = gpio->out; 39615fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 39715fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell status = gpiochip_add(&gpio->chip); 39815fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell if (status < 0) 39915fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell goto fail; 40015fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 40115fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell /* Let platform code set up the GPIOs and their users. 40215fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell * Now is the first time anyone could use them. 40315fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell */ 40449946f68149a723659eca253376ac555d4b73280Dmitry Eremin-Solenikov if (pdata && pdata->setup) { 40515fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell status = pdata->setup(client, 40615fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell gpio->chip.base, gpio->chip.ngpio, 40715fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell pdata->context); 40815fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell if (status < 0) 40915fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell dev_warn(&client->dev, "setup --> %d\n", status); 41015fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell } 41115fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 412805f864ebefc39065b6b0cf2548f13c2fbf888d9Kuninori Morimoto dev_info(&client->dev, "probed\n"); 413805f864ebefc39065b6b0cf2548f13c2fbf888d9Kuninori Morimoto 41415fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell return 0; 41515fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 41615fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownellfail: 417655c4e79370d1731c293c47aaf85d4c990a33052Laurent Pinchart if (client->irq) 4186e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto pcf857x_irq_domain_cleanup(gpio); 4196e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto 420e6b698f69adce0119b5f5ed00789d1a0e0af975fGeorge Cherianfail_irq_domain: 421e6b698f69adce0119b5f5ed00789d1a0e0af975fGeorge Cherian dev_dbg(&client->dev, "probe error %d for '%s'\n", 422e6b698f69adce0119b5f5ed00789d1a0e0af975fGeorge Cherian status, client->name); 423e6b698f69adce0119b5f5ed00789d1a0e0af975fGeorge Cherian 42415fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell return status; 42515fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell} 42615fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 42715fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownellstatic int pcf857x_remove(struct i2c_client *client) 42815fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell{ 429e56aee1897fd27631c1cb28e12b0fb8f8f9736f7Jingoo Han struct pcf857x_platform_data *pdata = dev_get_platdata(&client->dev); 43015fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell struct pcf857x *gpio = i2c_get_clientdata(client); 43115fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell int status = 0; 43215fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 43349946f68149a723659eca253376ac555d4b73280Dmitry Eremin-Solenikov if (pdata && pdata->teardown) { 43415fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell status = pdata->teardown(client, 43515fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell gpio->chip.base, gpio->chip.ngpio, 43615fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell pdata->context); 43715fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell if (status < 0) { 43815fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell dev_err(&client->dev, "%s --> %d\n", 43915fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell "teardown", status); 44015fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell return status; 44115fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell } 44215fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell } 44315fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 444655c4e79370d1731c293c47aaf85d4c990a33052Laurent Pinchart if (client->irq) 4456e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto pcf857x_irq_domain_cleanup(gpio); 4466e20a0a429bd4dc07d6de16d9c247270e04e4aa0Kuninori Morimoto 4479f5132ae82fdbb047cc187bf689a81c8cc0de7faabdoulaye berthe gpiochip_remove(&gpio->chip); 44815fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell return status; 44915fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell} 45015fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 45115fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownellstatic struct i2c_driver pcf857x_driver = { 45215fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell .driver = { 45315fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell .name = "pcf857x", 45415fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell .owner = THIS_MODULE, 45563f57cd45b0811de9663edf4af6b170c5bd3860dLaurent Pinchart .of_match_table = of_match_ptr(pcf857x_of_table), 45615fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell }, 45715fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell .probe = pcf857x_probe, 45815fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell .remove = pcf857x_remove, 4593760f736716f74bdc62a4ba5406934338da93eb2Jean Delvare .id_table = pcf857x_id, 46015fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell}; 46115fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 46215fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownellstatic int __init pcf857x_init(void) 46315fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell{ 46415fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell return i2c_add_driver(&pcf857x_driver); 46515fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell} 4662f8d11971b9f54362437ce70f4d1911f0996d542David Brownell/* register after i2c postcore initcall and before 4672f8d11971b9f54362437ce70f4d1911f0996d542David Brownell * subsys initcalls that may rely on these GPIOs 4682f8d11971b9f54362437ce70f4d1911f0996d542David Brownell */ 4692f8d11971b9f54362437ce70f4d1911f0996d542David Brownellsubsys_initcall(pcf857x_init); 47015fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 47115fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownellstatic void __exit pcf857x_exit(void) 47215fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell{ 47315fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell i2c_del_driver(&pcf857x_driver); 47415fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell} 47515fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownellmodule_exit(pcf857x_exit); 47615fae37d9f5f21571a9618d8353164b6ddfea6f6David Brownell 47715fae37d9f5f21571a9618d8353164b6ddfea6f6David BrownellMODULE_LICENSE("GPL"); 47815fae37d9f5f21571a9618d8353164b6ddfea6f6David BrownellMODULE_AUTHOR("David Brownell"); 479