From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3AE83560AC3; Wed, 9 Sep 2026 13:24:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788960263; cv=none; b=pTFQgxdpuoQfDxtGLXqW1vYndmS/LQRVabJxG94i8tTuVyw211GUqkTA9C1ESmCPYgLw61wecAE4bIaqralkGkRXLTMeYp0c72P5NoO/F0XR7gfoKNjAqcDt8yADdXNyY/xvU7EcEPkuutsT672jrP/oBo2po7r2z6WqSlQDk0Y= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788960263; c=relaxed/simple; bh=NO4G5eYBdbhMd5sw67d/eqUiBQ8PQcOJvjXe7aSIJgU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VjYyqVtirm3NvkTSyzKfEHhbAPj+5iS05Q75d0pN51XKf0jyWtw0ixzmCLq5Y8WCta2Bcdm7uSOKGotFP9gLseb41rSH8cVSw05T9DD/Ou8tmbZXNzec4kULhFAcXmuZkrnQF6Ay0gCRNkZGUhqXew/bixwNghcLorD0MXh3/QE= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=d+JiQCIK; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="d+JiQCIK" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C747C1F00A3F; Wed, 9 Sep 2026 13:23:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1788960243; bh=GsvUef4hneB+xdHcxkeILGXl9Km9+VtxY+PwGgE+eto=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=d+JiQCIKd3jlqqdaDOteHFuE3oG36JyWUU+QWxk/n59ROKREnLLnr5WsLTb/dbd8L TPYEzmQIQ8Ym5n29AU5nqJ5FW67xXpBkMFFbpJ0AmjUYdaxaiVP8kFXbY1KTiTVA1n oXATGrn9c3jdn9KFcxvC5wrDXA+UN0S3zZvJRgYaJpcbunvy3t6vaEuyxsi9ym+1DC R3WpH0TtC77Zu3s2j9csObvAri9x3Q1R6JRZ20sM2vdysNr2fZu7hvZJMz7xXlzh5v KMhh5pIn8Lqh+TzFPcmbq+ZTpfzm2Hykvic25JUD39YmziT4GSfSsqmNbyKTODNYjg ucMA2X1FARVvQ== From: Arnd Bergmann To: Lee Jones , mfd@lists.linux.dev Cc: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Arnd Bergmann , Daniel Thompson , Jingoo Han , Mauro Carvalho Chehab , Liam Girdwood , Mark Brown , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Guenter Roeck , Linus Walleij , Bartosz Golaszewski , Jonathan Cameron , Dmitry Torokhov , Pavel Machek , Michael Hennerich , Support Opensource , Sebastian Reichel , Alexandre Belloni , Helge Deller , dri-devel@lists.freedesktop.org, linux-doc@vger.kernel.org, linux-media@vger.kernel.org, devicetree@vger.kernel.org, linux-hwmon@vger.kernel.org, patches@opensource.cirrus.com, linux-watchdog@vger.kernel.org, linux-gpio@vger.kernel.org, linux-iio@vger.kernel.org, linux-input@vger.kernel.org, linux-leds@vger.kernel.org, linux-pm@vger.kernel.org, linux-rtc@vger.kernel.org, linux-fbdev@vger.kernel.org, linux-sound@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, llvm@lists.linux.dev Subject: [PATCH 12/14] mfd: remove unused mcp-sa11x0/ucb1x00 driver Date: Wed, 9 Sep 2026 15:21:49 +0200 Message-ID: <20260909132153.1596191-13-arnd@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260909132153.1596191-1-arnd@kernel.org> References: <20260909132153.1596191-1-arnd@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Arnd Bergmann The sa1100 platform has been removed, so these drivers are no longer used anywhere. Signed-off-by: Arnd Bergmann --- Documentation/admin-guide/devices.txt | 1 - drivers/mfd/Kconfig | 24 - drivers/mfd/Makefile | 8 - drivers/mfd/mcp-core.c | 235 ------ drivers/mfd/mcp-sa11x0.c | 304 ------- drivers/mfd/ucb1x00-assabet.c | 175 ---- drivers/mfd/ucb1x00-core.c | 795 ------------------- drivers/mfd/ucb1x00-ts.c | 445 ----------- include/linux/mfd/mcp.h | 63 -- include/linux/mfd/ucb1x00.h | 261 ------ include/linux/platform_data/mfd-mcp-sa11x0.h | 17 - 11 files changed, 2328 deletions(-) delete mode 100644 drivers/mfd/mcp-core.c delete mode 100644 drivers/mfd/mcp-sa11x0.c delete mode 100644 drivers/mfd/ucb1x00-assabet.c delete mode 100644 drivers/mfd/ucb1x00-core.c delete mode 100644 drivers/mfd/ucb1x00-ts.c delete mode 100644 include/linux/mfd/mcp.h delete mode 100644 include/linux/mfd/ucb1x00.h delete mode 100644 include/linux/platform_data/mfd-mcp-sa11x0.h diff --git a/Documentation/admin-guide/devices.txt b/Documentation/admin-guide/devices.txt index f544399675fa..eaaa03118fc1 100644 --- a/Documentation/admin-guide/devices.txt +++ b/Documentation/admin-guide/devices.txt @@ -262,7 +262,6 @@ 10 = /dev/adbmouse Apple Desktop Bus mouse 11 = /dev/vrtpanel Vr41xx embedded touch panel 13 = /dev/vpcmouse Connectix Virtual PC Mouse - 14 = /dev/touchscreen/ucb1x00 UCB 1x00 touchscreen 15 = /dev/touchscreen/mk712 MK712 touchscreen 128 = /dev/beep Fancy beep device 129 = diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 8a3bbb628693..0395af7270f9 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -2258,30 +2258,6 @@ config MFD_QCOM_PM8008 under it in the device tree. Additional drivers must be enabled in order to use the functionality of the device. -menu "Multimedia Capabilities Port drivers" - depends on ARCH_SA1100 - -config MCP - tristate - -# Interface drivers -config MCP_SA11X0 - tristate "Support SA11x0 MCP interface" - depends on ARCH_SA1100 - select MCP - -# Chip drivers -config MCP_UCB1200 - tristate "Support for UCB1200 / UCB1300" - depends on MCP_SA11X0 - select MCP - -config MCP_UCB1200_TS - tristate "Touchscreen interface support" - depends on MCP_UCB1200 && INPUT - -endmenu - config MFD_VEXPRESS_SYSREG tristate "Versatile Express System Registers" depends on VEXPRESS_CONFIG && GPIOLIB diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 2cdbc693ee33..ff62e922209e 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -126,14 +126,6 @@ obj-$(CONFIG_MFD_OCELOT) += ocelot-soc.o obj-$(CONFIG_MFD_CPCAP) += motorola-cpcap.o -obj-$(CONFIG_MCP) += mcp-core.o -obj-$(CONFIG_MCP_SA11X0) += mcp-sa11x0.o -obj-$(CONFIG_MCP_UCB1200) += ucb1x00-core.o -obj-$(CONFIG_MCP_UCB1200_TS) += ucb1x00-ts.o - -ifeq ($(CONFIG_SA1100_ASSABET),y) -obj-$(CONFIG_MCP_UCB1200) += ucb1x00-assabet.o -endif obj-$(CONFIG_PMIC_DA9052) += da9052-irq.o obj-$(CONFIG_PMIC_DA9052) += da9052-core.o diff --git a/drivers/mfd/mcp-core.c b/drivers/mfd/mcp-core.c deleted file mode 100644 index be08eaee0a90..000000000000 --- a/drivers/mfd/mcp-core.c +++ /dev/null @@ -1,235 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * linux/drivers/mfd/mcp-core.c - * - * Copyright (C) 2001 Russell King - * - * Generic MCP (Multimedia Communications Port) layer. All MCP locking - * is solely held within this file. - */ -#include -#include -#include -#include -#include -#include -#include -#include - - -#define to_mcp(d) container_of(d, struct mcp, attached_device) -#define to_mcp_driver(d) container_of(d, struct mcp_driver, drv) - -static int mcp_bus_match(struct device *dev, const struct device_driver *drv) -{ - return 1; -} - -static int mcp_bus_probe(struct device *dev) -{ - struct mcp *mcp = to_mcp(dev); - struct mcp_driver *drv = to_mcp_driver(dev->driver); - - return drv->probe(mcp); -} - -static void mcp_bus_remove(struct device *dev) -{ - struct mcp *mcp = to_mcp(dev); - struct mcp_driver *drv = to_mcp_driver(dev->driver); - - drv->remove(mcp); -} - -static const struct bus_type mcp_bus_type = { - .name = "mcp", - .match = mcp_bus_match, - .probe = mcp_bus_probe, - .remove = mcp_bus_remove, -}; - -/** - * mcp_set_telecom_divisor - set the telecom divisor - * @mcp: MCP interface structure - * @div: SIB clock divisor - * - * Set the telecom divisor on the MCP interface. The resulting - * sample rate is SIBCLOCK/div. - */ -void mcp_set_telecom_divisor(struct mcp *mcp, unsigned int div) -{ - unsigned long flags; - - spin_lock_irqsave(&mcp->lock, flags); - mcp->ops->set_telecom_divisor(mcp, div); - spin_unlock_irqrestore(&mcp->lock, flags); -} -EXPORT_SYMBOL(mcp_set_telecom_divisor); - -/** - * mcp_set_audio_divisor - set the audio divisor - * @mcp: MCP interface structure - * @div: SIB clock divisor - * - * Set the audio divisor on the MCP interface. - */ -void mcp_set_audio_divisor(struct mcp *mcp, unsigned int div) -{ - unsigned long flags; - - spin_lock_irqsave(&mcp->lock, flags); - mcp->ops->set_audio_divisor(mcp, div); - spin_unlock_irqrestore(&mcp->lock, flags); -} -EXPORT_SYMBOL(mcp_set_audio_divisor); - -/** - * mcp_reg_write - write a device register - * @mcp: MCP interface structure - * @reg: 4-bit register index - * @val: 16-bit data value - * - * Write a device register. The MCP interface must be enabled - * to prevent this function hanging. - */ -void mcp_reg_write(struct mcp *mcp, unsigned int reg, unsigned int val) -{ - unsigned long flags; - - spin_lock_irqsave(&mcp->lock, flags); - mcp->ops->reg_write(mcp, reg, val); - spin_unlock_irqrestore(&mcp->lock, flags); -} -EXPORT_SYMBOL(mcp_reg_write); - -/** - * mcp_reg_read - read a device register - * @mcp: MCP interface structure - * @reg: 4-bit register index - * - * Read a device register and return its value. The MCP interface - * must be enabled to prevent this function hanging. - */ -unsigned int mcp_reg_read(struct mcp *mcp, unsigned int reg) -{ - unsigned long flags; - unsigned int val; - - spin_lock_irqsave(&mcp->lock, flags); - val = mcp->ops->reg_read(mcp, reg); - spin_unlock_irqrestore(&mcp->lock, flags); - - return val; -} -EXPORT_SYMBOL(mcp_reg_read); - -/** - * mcp_enable - enable the MCP interface - * @mcp: MCP interface to enable - * - * Enable the MCP interface. Each call to mcp_enable will need - * a corresponding call to mcp_disable to disable the interface. - */ -void mcp_enable(struct mcp *mcp) -{ - unsigned long flags; - - spin_lock_irqsave(&mcp->lock, flags); - if (mcp->use_count++ == 0) - mcp->ops->enable(mcp); - spin_unlock_irqrestore(&mcp->lock, flags); -} -EXPORT_SYMBOL(mcp_enable); - -/** - * mcp_disable - disable the MCP interface - * @mcp: MCP interface to disable - * - * Disable the MCP interface. The MCP interface will only be - * disabled once the number of calls to mcp_enable matches the - * number of calls to mcp_disable. - */ -void mcp_disable(struct mcp *mcp) -{ - unsigned long flags; - - spin_lock_irqsave(&mcp->lock, flags); - if (--mcp->use_count == 0) - mcp->ops->disable(mcp); - spin_unlock_irqrestore(&mcp->lock, flags); -} -EXPORT_SYMBOL(mcp_disable); - -static void mcp_release(struct device *dev) -{ - struct mcp *mcp = container_of(dev, struct mcp, attached_device); - - kfree(mcp); -} - -struct mcp *mcp_host_alloc(struct device *parent, size_t size) -{ - struct mcp *mcp; - - mcp = kzalloc(sizeof(struct mcp) + size, GFP_KERNEL); - if (mcp) { - spin_lock_init(&mcp->lock); - device_initialize(&mcp->attached_device); - mcp->attached_device.parent = parent; - mcp->attached_device.bus = &mcp_bus_type; - mcp->attached_device.dma_mask = parent->dma_mask; - mcp->attached_device.release = mcp_release; - } - return mcp; -} -EXPORT_SYMBOL(mcp_host_alloc); - -int mcp_host_add(struct mcp *mcp, void *pdata) -{ - mcp->attached_device.platform_data = pdata; - dev_set_name(&mcp->attached_device, "mcp0"); - return device_add(&mcp->attached_device); -} -EXPORT_SYMBOL(mcp_host_add); - -void mcp_host_del(struct mcp *mcp) -{ - device_del(&mcp->attached_device); -} -EXPORT_SYMBOL(mcp_host_del); - -void mcp_host_free(struct mcp *mcp) -{ - put_device(&mcp->attached_device); -} -EXPORT_SYMBOL(mcp_host_free); - -int mcp_driver_register(struct mcp_driver *mcpdrv) -{ - mcpdrv->drv.bus = &mcp_bus_type; - return driver_register(&mcpdrv->drv); -} -EXPORT_SYMBOL(mcp_driver_register); - -void mcp_driver_unregister(struct mcp_driver *mcpdrv) -{ - driver_unregister(&mcpdrv->drv); -} -EXPORT_SYMBOL(mcp_driver_unregister); - -static int __init mcp_init(void) -{ - return bus_register(&mcp_bus_type); -} - -static void __exit mcp_exit(void) -{ - bus_unregister(&mcp_bus_type); -} - -module_init(mcp_init); -module_exit(mcp_exit); - -MODULE_AUTHOR("Russell King "); -MODULE_DESCRIPTION("Core multimedia communications port driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/mfd/mcp-sa11x0.c b/drivers/mfd/mcp-sa11x0.c deleted file mode 100644 index 228c4a2f4c1f..000000000000 --- a/drivers/mfd/mcp-sa11x0.c +++ /dev/null @@ -1,304 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * linux/drivers/mfd/mcp-sa11x0.c - * - * Copyright (C) 2001-2005 Russell King - * - * SA11x0 MCP (Multimedia Communications Port) driver. - * - * MCP read/write timeouts from Jordi Colomer, rehacked by rmk. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#define DRIVER_NAME "sa11x0-mcp" - -struct mcp_sa11x0 { - void __iomem *base0; - void __iomem *base1; - u32 mccr0; - u32 mccr1; -}; - -/* Register offsets */ -#define MCCR0(m) ((m)->base0 + 0x00) -#define MCDR0(m) ((m)->base0 + 0x08) -#define MCDR1(m) ((m)->base0 + 0x0c) -#define MCDR2(m) ((m)->base0 + 0x10) -#define MCSR(m) ((m)->base0 + 0x18) -#define MCCR1(m) ((m)->base1 + 0x00) - -#define priv(mcp) ((struct mcp_sa11x0 *)mcp_priv(mcp)) - -static void -mcp_sa11x0_set_telecom_divisor(struct mcp *mcp, unsigned int divisor) -{ - struct mcp_sa11x0 *m = priv(mcp); - - divisor /= 32; - - m->mccr0 &= ~0x00007f00; - m->mccr0 |= divisor << 8; - writel_relaxed(m->mccr0, MCCR0(m)); -} - -static void -mcp_sa11x0_set_audio_divisor(struct mcp *mcp, unsigned int divisor) -{ - struct mcp_sa11x0 *m = priv(mcp); - - divisor /= 32; - - m->mccr0 &= ~0x0000007f; - m->mccr0 |= divisor; - writel_relaxed(m->mccr0, MCCR0(m)); -} - -/* - * Write data to the device. The bit should be set after 3 subframe - * times (each frame is 64 clocks). We wait a maximum of 6 subframes. - * We really should try doing something more productive while we - * wait. - */ -static void -mcp_sa11x0_write(struct mcp *mcp, unsigned int reg, unsigned int val) -{ - struct mcp_sa11x0 *m = priv(mcp); - int ret = -ETIME; - int i; - - writel_relaxed(reg << 17 | MCDR2_Wr | (val & 0xffff), MCDR2(m)); - - for (i = 0; i < 2; i++) { - udelay(mcp->rw_timeout); - if (readl_relaxed(MCSR(m)) & MCSR_CWC) { - ret = 0; - break; - } - } - - if (ret < 0) - printk(KERN_WARNING "mcp: write timed out\n"); -} - -/* - * Read data from the device. The bit should be set after 3 subframe - * times (each frame is 64 clocks). We wait a maximum of 6 subframes. - * We really should try doing something more productive while we - * wait. - */ -static unsigned int -mcp_sa11x0_read(struct mcp *mcp, unsigned int reg) -{ - struct mcp_sa11x0 *m = priv(mcp); - int ret = -ETIME; - int i; - - writel_relaxed(reg << 17 | MCDR2_Rd, MCDR2(m)); - - for (i = 0; i < 2; i++) { - udelay(mcp->rw_timeout); - if (readl_relaxed(MCSR(m)) & MCSR_CRC) { - ret = readl_relaxed(MCDR2(m)) & 0xffff; - break; - } - } - - if (ret < 0) - printk(KERN_WARNING "mcp: read timed out\n"); - - return ret; -} - -static void mcp_sa11x0_enable(struct mcp *mcp) -{ - struct mcp_sa11x0 *m = priv(mcp); - - writel(-1, MCSR(m)); - m->mccr0 |= MCCR0_MCE; - writel_relaxed(m->mccr0, MCCR0(m)); -} - -static void mcp_sa11x0_disable(struct mcp *mcp) -{ - struct mcp_sa11x0 *m = priv(mcp); - - m->mccr0 &= ~MCCR0_MCE; - writel_relaxed(m->mccr0, MCCR0(m)); -} - -/* - * Our methods. - */ -static struct mcp_ops mcp_sa11x0 = { - .set_telecom_divisor = mcp_sa11x0_set_telecom_divisor, - .set_audio_divisor = mcp_sa11x0_set_audio_divisor, - .reg_write = mcp_sa11x0_write, - .reg_read = mcp_sa11x0_read, - .enable = mcp_sa11x0_enable, - .disable = mcp_sa11x0_disable, -}; - -static int mcp_sa11x0_probe(struct platform_device *dev) -{ - struct mcp_plat_data *data = dev_get_platdata(&dev->dev); - struct resource *mem0, *mem1; - struct mcp_sa11x0 *m; - struct mcp *mcp; - int ret; - - if (!data) - return -ENODEV; - - mem0 = platform_get_resource(dev, IORESOURCE_MEM, 0); - mem1 = platform_get_resource(dev, IORESOURCE_MEM, 1); - if (!mem0 || !mem1) - return -ENXIO; - - if (!request_mem_region(mem0->start, resource_size(mem0), - DRIVER_NAME)) { - ret = -EBUSY; - goto err_mem0; - } - - if (!request_mem_region(mem1->start, resource_size(mem1), - DRIVER_NAME)) { - ret = -EBUSY; - goto err_mem1; - } - - mcp = mcp_host_alloc(&dev->dev, sizeof(struct mcp_sa11x0)); - if (!mcp) { - ret = -ENOMEM; - goto err_alloc; - } - - mcp->owner = THIS_MODULE; - mcp->ops = &mcp_sa11x0; - mcp->sclk_rate = data->sclk_rate; - - m = priv(mcp); - m->mccr0 = data->mccr0 | 0x7f7f; - m->mccr1 = data->mccr1; - - m->base0 = ioremap(mem0->start, resource_size(mem0)); - m->base1 = ioremap(mem1->start, resource_size(mem1)); - if (!m->base0 || !m->base1) { - ret = -ENOMEM; - goto err_ioremap; - } - - platform_set_drvdata(dev, mcp); - - /* - * Initialise device. Note that we initially - * set the sampling rate to minimum. - */ - writel_relaxed(-1, MCSR(m)); - writel_relaxed(m->mccr1, MCCR1(m)); - writel_relaxed(m->mccr0, MCCR0(m)); - - /* - * Calculate the read/write timeout (us) from the bit clock - * rate. This is the period for 3 64-bit frames. Always - * round this time up. - */ - mcp->rw_timeout = DIV_ROUND_UP(64 * 3 * 1000000, mcp->sclk_rate); - - ret = mcp_host_add(mcp, data->codec_pdata); - if (ret == 0) - return 0; - - err_ioremap: - iounmap(m->base1); - iounmap(m->base0); - mcp_host_free(mcp); - err_alloc: - release_mem_region(mem1->start, resource_size(mem1)); - err_mem1: - release_mem_region(mem0->start, resource_size(mem0)); - err_mem0: - return ret; -} - -static void mcp_sa11x0_remove(struct platform_device *dev) -{ - struct mcp *mcp = platform_get_drvdata(dev); - struct mcp_sa11x0 *m = priv(mcp); - struct resource *mem0, *mem1; - - if (m->mccr0 & MCCR0_MCE) - dev_warn(&dev->dev, - "device left active (missing disable call?)\n"); - - mem0 = platform_get_resource(dev, IORESOURCE_MEM, 0); - mem1 = platform_get_resource(dev, IORESOURCE_MEM, 1); - - mcp_host_del(mcp); - iounmap(m->base1); - iounmap(m->base0); - mcp_host_free(mcp); - release_mem_region(mem1->start, resource_size(mem1)); - release_mem_region(mem0->start, resource_size(mem0)); -} - -static int mcp_sa11x0_suspend(struct device *dev) -{ - struct mcp_sa11x0 *m = priv(dev_get_drvdata(dev)); - - if (m->mccr0 & MCCR0_MCE) - dev_warn(dev, "device left active (missing disable call?)\n"); - - writel(m->mccr0 & ~MCCR0_MCE, MCCR0(m)); - - return 0; -} - -static int mcp_sa11x0_resume(struct device *dev) -{ - struct mcp_sa11x0 *m = priv(dev_get_drvdata(dev)); - - writel_relaxed(m->mccr1, MCCR1(m)); - writel_relaxed(m->mccr0, MCCR0(m)); - - return 0; -} - -static const struct dev_pm_ops mcp_sa11x0_pm_ops = { - .suspend = mcp_sa11x0_suspend, - .freeze = mcp_sa11x0_suspend, - .poweroff = mcp_sa11x0_suspend, - .resume_noirq = mcp_sa11x0_resume, - .thaw_noirq = mcp_sa11x0_resume, - .restore_noirq = mcp_sa11x0_resume, -}; - -static struct platform_driver mcp_sa11x0_driver = { - .probe = mcp_sa11x0_probe, - .remove = mcp_sa11x0_remove, - .driver = { - .name = DRIVER_NAME, - .pm = pm_sleep_ptr(&mcp_sa11x0_pm_ops), - }, -}; - -/* - * This needs re-working - */ -module_platform_driver(mcp_sa11x0_driver); - -MODULE_ALIAS("platform:" DRIVER_NAME); -MODULE_AUTHOR("Russell King "); -MODULE_DESCRIPTION("SA11x0 multimedia communications port driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/mfd/ucb1x00-assabet.c b/drivers/mfd/ucb1x00-assabet.c deleted file mode 100644 index 698f60aa9756..000000000000 --- a/drivers/mfd/ucb1x00-assabet.c +++ /dev/null @@ -1,175 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * linux/drivers/mfd/ucb1x00-assabet.c - * - * Copyright (C) 2001-2003 Russell King, All Rights Reserved. - * - * We handle the machine-specific bits of the UCB1x00 driver here. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define UCB1X00_ATTR(name,input)\ -static ssize_t name##_show(struct device *dev, struct device_attribute *attr, \ - char *buf) \ -{ \ - struct ucb1x00 *ucb = classdev_to_ucb1x00(dev); \ - int val; \ - ucb1x00_adc_enable(ucb); \ - val = ucb1x00_adc_read(ucb, input, UCB_NOSYNC); \ - ucb1x00_adc_disable(ucb); \ - return sprintf(buf, "%d\n", val); \ -} \ -static DEVICE_ATTR_RO(name) - -UCB1X00_ATTR(vbatt, UCB_ADC_INP_AD1); -UCB1X00_ATTR(vcharger, UCB_ADC_INP_AD0); -UCB1X00_ATTR(batt_temp, UCB_ADC_INP_AD2); - -static const struct property_entry ucb1x00_gpio_keys_props[] = { - PROPERTY_ENTRY_STRING("label", "ucb1x00"), - PROPERTY_ENTRY_U32("poll-interval", 50), - { } -}; - -#define UCB1X00_BTN_PROPS(_idx) \ -struct property_entry ucb1x00_btn##_idx##_props[] = { \ - PROPERTY_ENTRY_U32("linux,code", BTN_0 + (_idx)), \ - PROPERTY_ENTRY_GPIO("gpios", &ucb1x00_gpiochip_node, \ - _idx, GPIO_ACTIVE_HIGH), \ - PROPERTY_ENTRY_STRING("label", "btn" #_idx), \ - PROPERTY_ENTRY_BOOL("linux,can-disable"), \ - { } \ -} - -static const UCB1X00_BTN_PROPS(0); -static const UCB1X00_BTN_PROPS(1); -static const UCB1X00_BTN_PROPS(2); -static const UCB1X00_BTN_PROPS(3); -static const UCB1X00_BTN_PROPS(4); -static const UCB1X00_BTN_PROPS(5); - -static const struct property_entry * const ucb1x00_btn_props[] = { - ucb1x00_btn0_props, - ucb1x00_btn1_props, - ucb1x00_btn2_props, - ucb1x00_btn3_props, - ucb1x00_btn4_props, - ucb1x00_btn5_props, -}; - -struct ucb1x00_assabet_priv { - struct platform_device *pdev; - struct fwnode_handle *keys_node; - struct fwnode_handle *button_nodes[ARRAY_SIZE(ucb1x00_btn_props)]; -}; - -static void ucb1x00_assabet_remove_nodes(struct ucb1x00_assabet_priv *priv, int n) -{ - while (--n >= 0) - fwnode_remove_software_node(priv->button_nodes[n]); - - fwnode_remove_software_node(priv->keys_node); -} - -static int ucb1x00_assabet_add(struct ucb1x00_dev *dev) -{ - struct ucb1x00 *ucb = dev->ucb; - struct platform_device_info pdevinfo = { - .name = "gpio-keys", - .id = PLATFORM_DEVID_NONE, - .parent = &ucb->dev, - }; - int ret; - int i; - - struct ucb1x00_assabet_priv *priv; - - priv = kzalloc_obj(*priv); - if (!priv) - return -ENOMEM; - - priv->keys_node = fwnode_create_software_node(ucb1x00_gpio_keys_props, NULL); - if (IS_ERR(priv->keys_node)) { - ret = PTR_ERR(priv->keys_node); - goto err_free_priv; - } - - for (i = 0; i < ARRAY_SIZE(ucb1x00_btn_props); i++) { - priv->button_nodes[i] = fwnode_create_software_node(ucb1x00_btn_props[i], - priv->keys_node); - if (IS_ERR(priv->button_nodes[i])) { - ret = PTR_ERR(priv->button_nodes[i]); - goto err_free_buttons; - } - } - - pdevinfo.fwnode = priv->keys_node; - - priv->pdev = platform_device_register_full(&pdevinfo); - ret = PTR_ERR_OR_ZERO(priv->pdev); - if (ret) - goto err_free_buttons; - - device_create_file(&ucb->dev, &dev_attr_vbatt); - device_create_file(&ucb->dev, &dev_attr_vcharger); - device_create_file(&ucb->dev, &dev_attr_batt_temp); - - dev->priv = priv; - return 0; - -err_free_buttons: - ucb1x00_assabet_remove_nodes(priv, i); -err_free_priv: - kfree(priv); - return ret; -} - -static void ucb1x00_assabet_remove(struct ucb1x00_dev *dev) -{ - struct ucb1x00_assabet_priv *priv = dev->priv; - - if (!IS_ERR(priv->pdev)) - platform_device_unregister(priv->pdev); - - ucb1x00_assabet_remove_nodes(priv, ARRAY_SIZE(priv->button_nodes)); - - device_remove_file(&dev->ucb->dev, &dev_attr_batt_temp); - device_remove_file(&dev->ucb->dev, &dev_attr_vcharger); - device_remove_file(&dev->ucb->dev, &dev_attr_vbatt); - - kfree(priv); -} - -static struct ucb1x00_driver ucb1x00_assabet_driver = { - .add = ucb1x00_assabet_add, - .remove = ucb1x00_assabet_remove, -}; - -static int __init ucb1x00_assabet_init(void) -{ - return ucb1x00_register_driver(&ucb1x00_assabet_driver); -} - -static void __exit ucb1x00_assabet_exit(void) -{ - ucb1x00_unregister_driver(&ucb1x00_assabet_driver); -} - -module_init(ucb1x00_assabet_init); -module_exit(ucb1x00_assabet_exit); - -MODULE_AUTHOR("Russell King "); -MODULE_DESCRIPTION("Assabet noddy testing only example ADC driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c deleted file mode 100644 index 90edf0352d05..000000000000 --- a/drivers/mfd/ucb1x00-core.c +++ /dev/null @@ -1,795 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * linux/drivers/mfd/ucb1x00-core.c - * - * Copyright (C) 2001 Russell King, All Rights Reserved. - * - * The UCB1x00 core driver provides basic services for handling IO, - * the ADC, interrupts, and accessing registers. It is designed - * such that everything goes through this layer, thereby providing - * a consistent locking methodology, as well as allowing the drivers - * to be used on other non-MCP-enabled hardware platforms. - * - * Note that all locks are private to this file. Nothing else may - * touch them. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static DEFINE_MUTEX(ucb1x00_mutex); -static LIST_HEAD(ucb1x00_drivers); -static LIST_HEAD(ucb1x00_devices); - -/** - * ucb1x00_io_set_dir - set IO direction - * @ucb: UCB1x00 structure describing chip - * @in: bitfield of IO pins to be set as inputs - * @out: bitfield of IO pins to be set as outputs - * - * Set the IO direction of the ten general purpose IO pins on - * the UCB1x00 chip. The @in bitfield has priority over the - * @out bitfield, in that if you specify a pin as both input - * and output, it will end up as an input. - * - * ucb1x00_enable must have been called to enable the comms - * before using this function. - * - * This function takes a spinlock, disabling interrupts. - */ -void ucb1x00_io_set_dir(struct ucb1x00 *ucb, unsigned int in, unsigned int out) -{ - unsigned long flags; - - spin_lock_irqsave(&ucb->io_lock, flags); - ucb->io_dir |= out; - ucb->io_dir &= ~in; - - ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir); - spin_unlock_irqrestore(&ucb->io_lock, flags); -} - -/** - * ucb1x00_io_write - set or clear IO outputs - * @ucb: UCB1x00 structure describing chip - * @set: bitfield of IO pins to set to logic '1' - * @clear: bitfield of IO pins to set to logic '0' - * - * Set the IO output state of the specified IO pins. The value - * is retained if the pins are subsequently configured as inputs. - * The @clear bitfield has priority over the @set bitfield - - * outputs will be cleared. - * - * ucb1x00_enable must have been called to enable the comms - * before using this function. - * - * This function takes a spinlock, disabling interrupts. - */ -void ucb1x00_io_write(struct ucb1x00 *ucb, unsigned int set, unsigned int clear) -{ - unsigned long flags; - - spin_lock_irqsave(&ucb->io_lock, flags); - ucb->io_out |= set; - ucb->io_out &= ~clear; - - ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out); - spin_unlock_irqrestore(&ucb->io_lock, flags); -} - -/** - * ucb1x00_io_read - read the current state of the IO pins - * @ucb: UCB1x00 structure describing chip - * - * Return a bitfield describing the logic state of the ten - * general purpose IO pins. - * - * ucb1x00_enable must have been called to enable the comms - * before using this function. - * - * This function does not take any mutexes or spinlocks. - */ -unsigned int ucb1x00_io_read(struct ucb1x00 *ucb) -{ - return ucb1x00_reg_read(ucb, UCB_IO_DATA); -} - -static int ucb1x00_gpio_set(struct gpio_chip *chip, unsigned int offset, - int value) -{ - struct ucb1x00 *ucb = gpiochip_get_data(chip); - unsigned long flags; - - spin_lock_irqsave(&ucb->io_lock, flags); - if (value) - ucb->io_out |= 1 << offset; - else - ucb->io_out &= ~(1 << offset); - - ucb1x00_enable(ucb); - ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out); - ucb1x00_disable(ucb); - spin_unlock_irqrestore(&ucb->io_lock, flags); - - return 0; -} - -static int ucb1x00_gpio_get(struct gpio_chip *chip, unsigned offset) -{ - struct ucb1x00 *ucb = gpiochip_get_data(chip); - unsigned val; - - ucb1x00_enable(ucb); - val = ucb1x00_reg_read(ucb, UCB_IO_DATA); - ucb1x00_disable(ucb); - - return !!(val & (1 << offset)); -} - -static int ucb1x00_gpio_direction_input(struct gpio_chip *chip, unsigned offset) -{ - struct ucb1x00 *ucb = gpiochip_get_data(chip); - unsigned long flags; - - spin_lock_irqsave(&ucb->io_lock, flags); - ucb->io_dir &= ~(1 << offset); - ucb1x00_enable(ucb); - ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir); - ucb1x00_disable(ucb); - spin_unlock_irqrestore(&ucb->io_lock, flags); - - return 0; -} - -static int ucb1x00_gpio_direction_output(struct gpio_chip *chip, unsigned offset - , int value) -{ - struct ucb1x00 *ucb = gpiochip_get_data(chip); - unsigned long flags; - unsigned old, mask = 1 << offset; - - spin_lock_irqsave(&ucb->io_lock, flags); - old = ucb->io_out; - if (value) - ucb->io_out |= mask; - else - ucb->io_out &= ~mask; - - ucb1x00_enable(ucb); - if (old != ucb->io_out) - ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out); - - if (!(ucb->io_dir & mask)) { - ucb->io_dir |= mask; - ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir); - } - ucb1x00_disable(ucb); - spin_unlock_irqrestore(&ucb->io_lock, flags); - - return 0; -} - -static int ucb1x00_to_irq(struct gpio_chip *chip, unsigned offset) -{ - struct ucb1x00 *ucb = gpiochip_get_data(chip); - - return ucb->irq_base > 0 ? ucb->irq_base + offset : -ENXIO; -} - -/* - * UCB1300 data sheet says we must: - * 1. enable ADC => 5us (including reference startup time) - * 2. select input => 51*tsibclk => 4.3us - * 3. start conversion => 102*tsibclk => 8.5us - * (tsibclk = 1/11981000) - * Period between SIB 128-bit frames = 10.7us - */ - -/** - * ucb1x00_adc_enable - enable the ADC converter - * @ucb: UCB1x00 structure describing chip - * - * Enable the ucb1x00 and ADC converter on the UCB1x00 for use. - * Any code wishing to use the ADC converter must call this - * function prior to using it. - * - * This function takes the ADC mutex to prevent two or more - * concurrent uses, and therefore may sleep. As a result, it - * can only be called from process context, not interrupt - * context. - * - * You should release the ADC as soon as possible using - * ucb1x00_adc_disable. - */ -void ucb1x00_adc_enable(struct ucb1x00 *ucb) -{ - mutex_lock(&ucb->adc_mutex); - - ucb->adc_cr |= UCB_ADC_ENA; - - ucb1x00_enable(ucb); - ucb1x00_reg_write(ucb, UCB_ADC_CR, ucb->adc_cr); -} - -/** - * ucb1x00_adc_read - read the specified ADC channel - * @ucb: UCB1x00 structure describing chip - * @adc_channel: ADC channel mask - * @sync: wait for syncronisation pulse. - * - * Start an ADC conversion and wait for the result. Note that - * synchronised ADC conversions (via the ADCSYNC pin) must wait - * until the trigger is asserted and the conversion is finished. - * - * This function currently spins waiting for the conversion to - * complete (2 frames max without sync). - * - * If called for a synchronised ADC conversion, it may sleep - * with the ADC mutex held. - */ -unsigned int ucb1x00_adc_read(struct ucb1x00 *ucb, int adc_channel, int sync) -{ - unsigned int val; - - if (sync) - adc_channel |= UCB_ADC_SYNC_ENA; - - ucb1x00_reg_write(ucb, UCB_ADC_CR, ucb->adc_cr | adc_channel); - ucb1x00_reg_write(ucb, UCB_ADC_CR, ucb->adc_cr | adc_channel | UCB_ADC_START); - - for (;;) { - val = ucb1x00_reg_read(ucb, UCB_ADC_DATA); - if (val & UCB_ADC_DAT_VAL) - break; - /* yield to other processes */ - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(1); - } - - return UCB_ADC_DAT(val); -} - -/** - * ucb1x00_adc_disable - disable the ADC converter - * @ucb: UCB1x00 structure describing chip - * - * Disable the ADC converter and release the ADC mutex. - */ -void ucb1x00_adc_disable(struct ucb1x00 *ucb) -{ - ucb->adc_cr &= ~UCB_ADC_ENA; - ucb1x00_reg_write(ucb, UCB_ADC_CR, ucb->adc_cr); - ucb1x00_disable(ucb); - - mutex_unlock(&ucb->adc_mutex); -} - -/* - * UCB1x00 Interrupt handling. - * - * The UCB1x00 can generate interrupts when the SIBCLK is stopped. - * Since we need to read an internal register, we must re-enable - * SIBCLK to talk to the chip. We leave the clock running until - * we have finished processing all interrupts from the chip. - */ -static void ucb1x00_irq(struct irq_desc *desc) -{ - struct ucb1x00 *ucb = irq_desc_get_handler_data(desc); - unsigned int isr, i; - - ucb1x00_enable(ucb); - isr = ucb1x00_reg_read(ucb, UCB_IE_STATUS); - ucb1x00_reg_write(ucb, UCB_IE_CLEAR, isr); - ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0); - - for (i = 0; i < 16 && isr; i++, isr >>= 1) - if (isr & 1) - generic_handle_irq(ucb->irq_base + i); - ucb1x00_disable(ucb); -} - -static void ucb1x00_irq_update(struct ucb1x00 *ucb, unsigned mask) -{ - ucb1x00_enable(ucb); - if (ucb->irq_ris_enbl & mask) - ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl & - ucb->irq_mask); - if (ucb->irq_fal_enbl & mask) - ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl & - ucb->irq_mask); - ucb1x00_disable(ucb); -} - -static void ucb1x00_irq_noop(struct irq_data *data) -{ -} - -static void ucb1x00_irq_mask(struct irq_data *data) -{ - struct ucb1x00 *ucb = irq_data_get_irq_chip_data(data); - unsigned mask = 1 << (data->irq - ucb->irq_base); - - raw_spin_lock(&ucb->irq_lock); - ucb->irq_mask &= ~mask; - ucb1x00_irq_update(ucb, mask); - raw_spin_unlock(&ucb->irq_lock); -} - -static void ucb1x00_irq_unmask(struct irq_data *data) -{ - struct ucb1x00 *ucb = irq_data_get_irq_chip_data(data); - unsigned mask = 1 << (data->irq - ucb->irq_base); - - raw_spin_lock(&ucb->irq_lock); - ucb->irq_mask |= mask; - ucb1x00_irq_update(ucb, mask); - raw_spin_unlock(&ucb->irq_lock); -} - -static int ucb1x00_irq_set_type(struct irq_data *data, unsigned int type) -{ - struct ucb1x00 *ucb = irq_data_get_irq_chip_data(data); - unsigned mask = 1 << (data->irq - ucb->irq_base); - - raw_spin_lock(&ucb->irq_lock); - if (type & IRQ_TYPE_EDGE_RISING) - ucb->irq_ris_enbl |= mask; - else - ucb->irq_ris_enbl &= ~mask; - - if (type & IRQ_TYPE_EDGE_FALLING) - ucb->irq_fal_enbl |= mask; - else - ucb->irq_fal_enbl &= ~mask; - if (ucb->irq_mask & mask) { - ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl & - ucb->irq_mask); - ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl & - ucb->irq_mask); - } - raw_spin_unlock(&ucb->irq_lock); - - return 0; -} - -static int ucb1x00_irq_set_wake(struct irq_data *data, unsigned int on) -{ - struct ucb1x00 *ucb = irq_data_get_irq_chip_data(data); - struct ucb1x00_plat_data *pdata = ucb->mcp->attached_device.platform_data; - unsigned mask = 1 << (data->irq - ucb->irq_base); - - if (!pdata || !pdata->can_wakeup) - return -EINVAL; - - raw_spin_lock(&ucb->irq_lock); - if (on) - ucb->irq_wake |= mask; - else - ucb->irq_wake &= ~mask; - raw_spin_unlock(&ucb->irq_lock); - - return 0; -} - -static struct irq_chip ucb1x00_irqchip = { - .name = "ucb1x00", - .irq_ack = ucb1x00_irq_noop, - .irq_mask = ucb1x00_irq_mask, - .irq_unmask = ucb1x00_irq_unmask, - .irq_set_type = ucb1x00_irq_set_type, - .irq_set_wake = ucb1x00_irq_set_wake, -}; - -static int ucb1x00_add_dev(struct ucb1x00 *ucb, struct ucb1x00_driver *drv) -{ - struct ucb1x00_dev *dev; - int ret; - - dev = kmalloc_obj(struct ucb1x00_dev); - if (!dev) - return -ENOMEM; - - dev->ucb = ucb; - dev->drv = drv; - - ret = drv->add(dev); - if (ret) { - kfree(dev); - return ret; - } - - list_add_tail(&dev->dev_node, &ucb->devs); - list_add_tail(&dev->drv_node, &drv->devs); - - return ret; -} - -static void ucb1x00_remove_dev(struct ucb1x00_dev *dev) -{ - dev->drv->remove(dev); - list_del(&dev->dev_node); - list_del(&dev->drv_node); - kfree(dev); -} - -/* - * Try to probe our interrupt, rather than relying on lots of - * hard-coded machine dependencies. For reference, the expected - * IRQ mappings are: - * - * Machine Default IRQ - * adsbitsy IRQ_GPCIN4 - * cerf IRQ_GPIO_UCB1200_IRQ - * flexanet IRQ_GPIO_GUI - * freebird IRQ_GPIO_FREEBIRD_UCB1300_IRQ - * graphicsclient ADS_EXT_IRQ(8) - * graphicsmaster ADS_EXT_IRQ(8) - * lart LART_IRQ_UCB1200 - * omnimeter IRQ_GPIO23 - * pfs168 IRQ_GPIO_UCB1300_IRQ - * simpad IRQ_GPIO_UCB1300_IRQ - * shannon SHANNON_IRQ_GPIO_IRQ_CODEC - * yopy IRQ_GPIO_UCB1200_IRQ - */ -static int ucb1x00_detect_irq(struct ucb1x00 *ucb) -{ - unsigned long mask; - - mask = probe_irq_on(); - - /* - * Enable the ADC interrupt. - */ - ucb1x00_reg_write(ucb, UCB_IE_RIS, UCB_IE_ADC); - ucb1x00_reg_write(ucb, UCB_IE_FAL, UCB_IE_ADC); - ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0xffff); - ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0); - - /* - * Cause an ADC interrupt. - */ - ucb1x00_reg_write(ucb, UCB_ADC_CR, UCB_ADC_ENA); - ucb1x00_reg_write(ucb, UCB_ADC_CR, UCB_ADC_ENA | UCB_ADC_START); - - /* - * Wait for the conversion to complete. - */ - while ((ucb1x00_reg_read(ucb, UCB_ADC_DATA) & UCB_ADC_DAT_VAL) == 0); - ucb1x00_reg_write(ucb, UCB_ADC_CR, 0); - - /* - * Disable and clear interrupt. - */ - ucb1x00_reg_write(ucb, UCB_IE_RIS, 0); - ucb1x00_reg_write(ucb, UCB_IE_FAL, 0); - ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0xffff); - ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0); - - /* - * Read triggered interrupt. - */ - return probe_irq_off(mask); -} - -static void ucb1x00_release(struct device *dev) -{ - struct ucb1x00 *ucb = classdev_to_ucb1x00(dev); - kfree(ucb); -} - -static struct class ucb1x00_class = { - .name = "ucb1x00", - .dev_release = ucb1x00_release, -}; - -const struct software_node ucb1x00_gpiochip_node = { - .name = "ucb1x00-gpio", -}; -EXPORT_SYMBOL_GPL(ucb1x00_gpiochip_node); - -static int ucb1x00_probe(struct mcp *mcp) -{ - struct ucb1x00_plat_data *pdata = mcp->attached_device.platform_data; - struct ucb1x00_driver *drv; - struct ucb1x00 *ucb; - unsigned id, i, irq_base; - int ret = -ENODEV; - - /* Tell the platform to deassert the UCB1x00 reset */ - if (pdata && pdata->reset) - pdata->reset(UCB_RST_PROBE); - - mcp_enable(mcp); - id = mcp_reg_read(mcp, UCB_ID); - mcp_disable(mcp); - - if (id != UCB_ID_1200 && id != UCB_ID_1300 && id != UCB_ID_TC35143) { - printk(KERN_WARNING "UCB1x00 ID not found: %04x\n", id); - goto out; - } - - ucb = kzalloc_obj(struct ucb1x00); - ret = -ENOMEM; - if (!ucb) - goto out; - - device_initialize(&ucb->dev); - ucb->dev.class = &ucb1x00_class; - ucb->dev.parent = &mcp->attached_device; - dev_set_name(&ucb->dev, "ucb1x00"); - - raw_spin_lock_init(&ucb->irq_lock); - spin_lock_init(&ucb->io_lock); - mutex_init(&ucb->adc_mutex); - - ucb->id = id; - ucb->mcp = mcp; - - ret = device_add_software_node(&ucb->dev, &ucb1x00_gpiochip_node); - if (ret) - goto err_swnode_add; - - ret = device_add(&ucb->dev); - if (ret) - goto err_dev_add; - - ucb1x00_enable(ucb); - ucb->irq = ucb1x00_detect_irq(ucb); - ucb1x00_disable(ucb); - if (!ucb->irq) { - dev_err(&ucb->dev, "IRQ probe failed\n"); - ret = -ENODEV; - goto err_no_irq; - } - - ucb->gpio.base = -1; - irq_base = pdata ? pdata->irq_base : 0; - ucb->irq_base = irq_alloc_descs(-1, irq_base, 16, -1); - if (ucb->irq_base < 0) { - dev_err(&ucb->dev, "unable to allocate 16 irqs: %d\n", - ucb->irq_base); - ret = ucb->irq_base; - goto err_irq_alloc; - } - - for (i = 0; i < 16; i++) { - unsigned irq = ucb->irq_base + i; - - irq_set_chip_and_handler(irq, &ucb1x00_irqchip, handle_edge_irq); - irq_set_chip_data(irq, ucb); - irq_clear_status_flags(irq, IRQ_NOREQUEST); - } - - irq_set_irq_type(ucb->irq, IRQ_TYPE_EDGE_RISING); - irq_set_chained_handler_and_data(ucb->irq, ucb1x00_irq, ucb); - - if (pdata && pdata->gpio_base) { - ucb->gpio.label = dev_name(&ucb->dev); - ucb->gpio.parent = &ucb->dev; - ucb->gpio.owner = THIS_MODULE; - ucb->gpio.base = pdata->gpio_base; - ucb->gpio.ngpio = 10; - ucb->gpio.set = ucb1x00_gpio_set; - ucb->gpio.get = ucb1x00_gpio_get; - ucb->gpio.direction_input = ucb1x00_gpio_direction_input; - ucb->gpio.direction_output = ucb1x00_gpio_direction_output; - ucb->gpio.to_irq = ucb1x00_to_irq; - ret = gpiochip_add_data(&ucb->gpio, ucb); - if (ret) - goto err_gpio_add; - } else - dev_info(&ucb->dev, "gpio_base not set so no gpiolib support"); - - mcp_set_drvdata(mcp, ucb); - - if (pdata) - device_set_wakeup_capable(&ucb->dev, pdata->can_wakeup); - - INIT_LIST_HEAD(&ucb->devs); - mutex_lock(&ucb1x00_mutex); - list_add_tail(&ucb->node, &ucb1x00_devices); - list_for_each_entry(drv, &ucb1x00_drivers, node) { - ucb1x00_add_dev(ucb, drv); - } - mutex_unlock(&ucb1x00_mutex); - - return ret; - - err_gpio_add: - irq_set_chained_handler(ucb->irq, NULL); - err_irq_alloc: - if (ucb->irq_base > 0) - irq_free_descs(ucb->irq_base, 16); - err_no_irq: - device_del(&ucb->dev); - err_dev_add: - device_remove_software_node(&ucb->dev); - err_swnode_add: - put_device(&ucb->dev); - out: - if (pdata && pdata->reset) - pdata->reset(UCB_RST_PROBE_FAIL); - return ret; -} - -static void ucb1x00_remove(struct mcp *mcp) -{ - struct ucb1x00_plat_data *pdata = mcp->attached_device.platform_data; - struct ucb1x00 *ucb = mcp_get_drvdata(mcp); - struct list_head *l, *n; - - mutex_lock(&ucb1x00_mutex); - list_del(&ucb->node); - list_for_each_safe(l, n, &ucb->devs) { - struct ucb1x00_dev *dev = list_entry(l, struct ucb1x00_dev, dev_node); - ucb1x00_remove_dev(dev); - } - mutex_unlock(&ucb1x00_mutex); - - if (ucb->gpio.base != -1) - gpiochip_remove(&ucb->gpio); - - irq_set_chained_handler(ucb->irq, NULL); - irq_free_descs(ucb->irq_base, 16); - device_del(&ucb->dev); - device_remove_software_node(&ucb->dev); - put_device(&ucb->dev); - - if (pdata && pdata->reset) - pdata->reset(UCB_RST_REMOVE); -} - -int ucb1x00_register_driver(struct ucb1x00_driver *drv) -{ - struct ucb1x00 *ucb; - - INIT_LIST_HEAD(&drv->devs); - mutex_lock(&ucb1x00_mutex); - list_add_tail(&drv->node, &ucb1x00_drivers); - list_for_each_entry(ucb, &ucb1x00_devices, node) { - ucb1x00_add_dev(ucb, drv); - } - mutex_unlock(&ucb1x00_mutex); - return 0; -} - -void ucb1x00_unregister_driver(struct ucb1x00_driver *drv) -{ - struct list_head *n, *l; - - mutex_lock(&ucb1x00_mutex); - list_del(&drv->node); - list_for_each_safe(l, n, &drv->devs) { - struct ucb1x00_dev *dev = list_entry(l, struct ucb1x00_dev, drv_node); - ucb1x00_remove_dev(dev); - } - mutex_unlock(&ucb1x00_mutex); -} - -static int ucb1x00_suspend(struct device *dev) -{ - struct ucb1x00_plat_data *pdata = dev_get_platdata(dev); - struct ucb1x00 *ucb = dev_get_drvdata(dev); - struct ucb1x00_dev *udev; - - mutex_lock(&ucb1x00_mutex); - list_for_each_entry(udev, &ucb->devs, dev_node) { - if (udev->drv->suspend) - udev->drv->suspend(udev); - } - mutex_unlock(&ucb1x00_mutex); - - if (ucb->irq_wake) { - unsigned long flags; - - raw_spin_lock_irqsave(&ucb->irq_lock, flags); - ucb1x00_enable(ucb); - ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl & - ucb->irq_wake); - ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl & - ucb->irq_wake); - ucb1x00_disable(ucb); - raw_spin_unlock_irqrestore(&ucb->irq_lock, flags); - - enable_irq_wake(ucb->irq); - } else if (pdata && pdata->reset) - pdata->reset(UCB_RST_SUSPEND); - - return 0; -} - -static int ucb1x00_resume(struct device *dev) -{ - struct ucb1x00_plat_data *pdata = dev_get_platdata(dev); - struct ucb1x00 *ucb = dev_get_drvdata(dev); - struct ucb1x00_dev *udev; - - if (!ucb->irq_wake && pdata && pdata->reset) - pdata->reset(UCB_RST_RESUME); - - ucb1x00_enable(ucb); - ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out); - ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir); - - if (ucb->irq_wake) { - unsigned long flags; - - raw_spin_lock_irqsave(&ucb->irq_lock, flags); - ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl & - ucb->irq_mask); - ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl & - ucb->irq_mask); - raw_spin_unlock_irqrestore(&ucb->irq_lock, flags); - - disable_irq_wake(ucb->irq); - } - ucb1x00_disable(ucb); - - mutex_lock(&ucb1x00_mutex); - list_for_each_entry(udev, &ucb->devs, dev_node) { - if (udev->drv->resume) - udev->drv->resume(udev); - } - mutex_unlock(&ucb1x00_mutex); - return 0; -} - -static DEFINE_SIMPLE_DEV_PM_OPS(ucb1x00_pm_ops, - ucb1x00_suspend, ucb1x00_resume); - -static struct mcp_driver ucb1x00_driver = { - .drv = { - .name = "ucb1x00", - .owner = THIS_MODULE, - .pm = pm_sleep_ptr(&ucb1x00_pm_ops), - }, - .probe = ucb1x00_probe, - .remove = ucb1x00_remove, -}; - -static int __init ucb1x00_init(void) -{ - int ret = class_register(&ucb1x00_class); - if (ret == 0) { - ret = mcp_driver_register(&ucb1x00_driver); - if (ret) - class_unregister(&ucb1x00_class); - } - return ret; -} - -static void __exit ucb1x00_exit(void) -{ - mcp_driver_unregister(&ucb1x00_driver); - class_unregister(&ucb1x00_class); -} - -module_init(ucb1x00_init); -module_exit(ucb1x00_exit); - -EXPORT_SYMBOL(ucb1x00_io_set_dir); -EXPORT_SYMBOL(ucb1x00_io_write); -EXPORT_SYMBOL(ucb1x00_io_read); - -EXPORT_SYMBOL(ucb1x00_adc_enable); -EXPORT_SYMBOL(ucb1x00_adc_read); -EXPORT_SYMBOL(ucb1x00_adc_disable); - -EXPORT_SYMBOL(ucb1x00_register_driver); -EXPORT_SYMBOL(ucb1x00_unregister_driver); - -MODULE_ALIAS("mcp:ucb1x00"); -MODULE_AUTHOR("Russell King "); -MODULE_DESCRIPTION("UCB1x00 core driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c deleted file mode 100644 index 39fe187eea1f..000000000000 --- a/drivers/mfd/ucb1x00-ts.c +++ /dev/null @@ -1,445 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Touchscreen driver for UCB1x00-based touchscreens - * - * Copyright (C) 2001 Russell King, All Rights Reserved. - * Copyright (C) 2005 Pavel Machek - * - * 21-Jan-2002 : - * - * Added support for synchronous A/D mode. This mode is useful to - * avoid noise induced in the touchpanel by the LCD, provided that - * the UCB1x00 has a valid LCD sync signal routed to its ADCSYNC pin. - * It is important to note that the signal connected to the ADCSYNC - * pin should provide pulses even when the LCD is blanked, otherwise - * a pen touch needed to unblank the LCD will never be read. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - - - -struct ucb1x00_ts { - struct input_dev *idev; - struct ucb1x00 *ucb; - - spinlock_t irq_lock; - unsigned irq_disabled; - wait_queue_head_t irq_wait; - struct task_struct *rtask; - u16 x_res; - u16 y_res; - - unsigned int adcsync:1; -}; - -static int adcsync; - -static inline void ucb1x00_ts_evt_add(struct ucb1x00_ts *ts, u16 pressure, u16 x, u16 y) -{ - struct input_dev *idev = ts->idev; - - input_report_abs(idev, ABS_X, x); - input_report_abs(idev, ABS_Y, y); - input_report_abs(idev, ABS_PRESSURE, pressure); - input_report_key(idev, BTN_TOUCH, 1); - input_sync(idev); -} - -static inline void ucb1x00_ts_event_release(struct ucb1x00_ts *ts) -{ - struct input_dev *idev = ts->idev; - - input_report_abs(idev, ABS_PRESSURE, 0); - input_report_key(idev, BTN_TOUCH, 0); - input_sync(idev); -} - -/* - * Switch to interrupt mode. - */ -static inline void ucb1x00_ts_mode_int(struct ucb1x00_ts *ts) -{ - ucb1x00_reg_write(ts->ucb, UCB_TS_CR, - UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW | - UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND | - UCB_TS_CR_MODE_INT); -} - -/* - * Switch to pressure mode, and read pressure. We don't need to wait - * here, since both plates are being driven. - */ -static inline unsigned int ucb1x00_ts_read_pressure(struct ucb1x00_ts *ts) -{ - if (machine_is_collie()) { - ucb1x00_io_write(ts->ucb, COLLIE_TC35143_GPIO_TBL_CHK, 0); - ucb1x00_reg_write(ts->ucb, UCB_TS_CR, - UCB_TS_CR_TSPX_POW | UCB_TS_CR_TSMX_POW | - UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA); - - udelay(55); - - return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_AD2, ts->adcsync); - } else { - ucb1x00_reg_write(ts->ucb, UCB_TS_CR, - UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW | - UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND | - UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); - - return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync); - } -} - -/* - * Switch to X position mode and measure Y plate. We switch the plate - * configuration in pressure mode, then switch to position mode. This - * gives a faster response time. Even so, we need to wait about 55us - * for things to stabilise. - */ -static inline unsigned int ucb1x00_ts_read_xpos(struct ucb1x00_ts *ts) -{ - if (machine_is_collie()) - ucb1x00_io_write(ts->ucb, 0, COLLIE_TC35143_GPIO_TBL_CHK); - else { - ucb1x00_reg_write(ts->ucb, UCB_TS_CR, - UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW | - UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); - ucb1x00_reg_write(ts->ucb, UCB_TS_CR, - UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW | - UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); - } - ucb1x00_reg_write(ts->ucb, UCB_TS_CR, - UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW | - UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA); - - udelay(55); - - return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync); -} - -/* - * Switch to Y position mode and measure X plate. We switch the plate - * configuration in pressure mode, then switch to position mode. This - * gives a faster response time. Even so, we need to wait about 55us - * for things to stabilise. - */ -static inline unsigned int ucb1x00_ts_read_ypos(struct ucb1x00_ts *ts) -{ - if (machine_is_collie()) - ucb1x00_io_write(ts->ucb, 0, COLLIE_TC35143_GPIO_TBL_CHK); - else { - ucb1x00_reg_write(ts->ucb, UCB_TS_CR, - UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW | - UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); - ucb1x00_reg_write(ts->ucb, UCB_TS_CR, - UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW | - UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); - } - - ucb1x00_reg_write(ts->ucb, UCB_TS_CR, - UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW | - UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA); - - udelay(55); - - return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPX, ts->adcsync); -} - -/* - * Switch to X plate resistance mode. Set MX to ground, PX to - * supply. Measure current. - */ -static inline unsigned int ucb1x00_ts_read_xres(struct ucb1x00_ts *ts) -{ - ucb1x00_reg_write(ts->ucb, UCB_TS_CR, - UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW | - UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); - return ucb1x00_adc_read(ts->ucb, 0, ts->adcsync); -} - -/* - * Switch to Y plate resistance mode. Set MY to ground, PY to - * supply. Measure current. - */ -static inline unsigned int ucb1x00_ts_read_yres(struct ucb1x00_ts *ts) -{ - ucb1x00_reg_write(ts->ucb, UCB_TS_CR, - UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW | - UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); - return ucb1x00_adc_read(ts->ucb, 0, ts->adcsync); -} - -static inline int ucb1x00_ts_pen_down(struct ucb1x00_ts *ts) -{ - unsigned int val = ucb1x00_reg_read(ts->ucb, UCB_TS_CR); - - if (machine_is_collie()) - return (!(val & (UCB_TS_CR_TSPX_LOW))); - else - return (val & (UCB_TS_CR_TSPX_LOW | UCB_TS_CR_TSMX_LOW)); -} - -/* - * This is a RT kernel thread that handles the ADC accesses - * (mainly so we can use semaphores in the UCB1200 core code - * to serialise accesses to the ADC). - */ -static int ucb1x00_thread(void *_ts) -{ - struct ucb1x00_ts *ts = _ts; - DECLARE_WAITQUEUE(wait, current); - bool frozen, ignore = false; - int valid = 0; - - set_freezable(); - add_wait_queue(&ts->irq_wait, &wait); - while (!kthread_freezable_should_stop(&frozen)) { - unsigned int x, y, p; - signed long timeout; - - if (frozen) - ignore = true; - - ucb1x00_adc_enable(ts->ucb); - - x = ucb1x00_ts_read_xpos(ts); - y = ucb1x00_ts_read_ypos(ts); - p = ucb1x00_ts_read_pressure(ts); - - /* - * Switch back to interrupt mode. - */ - ucb1x00_ts_mode_int(ts); - ucb1x00_adc_disable(ts->ucb); - - msleep(10); - - ucb1x00_enable(ts->ucb); - - - if (ucb1x00_ts_pen_down(ts)) { - set_current_state(TASK_INTERRUPTIBLE); - - spin_lock_irq(&ts->irq_lock); - if (ts->irq_disabled) { - ts->irq_disabled = 0; - enable_irq(ts->ucb->irq_base + UCB_IRQ_TSPX); - } - spin_unlock_irq(&ts->irq_lock); - ucb1x00_disable(ts->ucb); - - /* - * If we spat out a valid sample set last time, - * spit out a "pen off" sample here. - */ - if (valid) { - ucb1x00_ts_event_release(ts); - valid = 0; - } - - timeout = MAX_SCHEDULE_TIMEOUT; - } else { - ucb1x00_disable(ts->ucb); - - /* - * Filtering is policy. Policy belongs in user - * space. We therefore leave it to user space - * to do any filtering they please. - */ - if (!ignore) { - ucb1x00_ts_evt_add(ts, p, x, y); - valid = 1; - } - - set_current_state(TASK_INTERRUPTIBLE); - timeout = HZ / 100; - } - - schedule_timeout(timeout); - } - - remove_wait_queue(&ts->irq_wait, &wait); - - ts->rtask = NULL; - return 0; -} - -/* - * We only detect touch screen _touches_ with this interrupt - * handler, and even then we just schedule our task. - */ -static irqreturn_t ucb1x00_ts_irq(int irq, void *id) -{ - struct ucb1x00_ts *ts = id; - - spin_lock(&ts->irq_lock); - ts->irq_disabled = 1; - disable_irq_nosync(ts->ucb->irq_base + UCB_IRQ_TSPX); - spin_unlock(&ts->irq_lock); - wake_up(&ts->irq_wait); - - return IRQ_HANDLED; -} - -static int ucb1x00_ts_open(struct input_dev *idev) -{ - struct ucb1x00_ts *ts = input_get_drvdata(idev); - unsigned long flags = 0; - int ret = 0; - - BUG_ON(ts->rtask); - - if (machine_is_collie()) - flags = IRQF_TRIGGER_RISING; - else - flags = IRQF_TRIGGER_FALLING; - - ts->irq_disabled = 0; - - init_waitqueue_head(&ts->irq_wait); - ret = request_irq(ts->ucb->irq_base + UCB_IRQ_TSPX, ucb1x00_ts_irq, - flags, "ucb1x00-ts", ts); - if (ret < 0) - goto out; - - /* - * If we do this at all, we should allow the user to - * measure and read the X and Y resistance at any time. - */ - ucb1x00_adc_enable(ts->ucb); - ts->x_res = ucb1x00_ts_read_xres(ts); - ts->y_res = ucb1x00_ts_read_yres(ts); - ucb1x00_adc_disable(ts->ucb); - - ts->rtask = kthread_run(ucb1x00_thread, ts, "ktsd"); - if (!IS_ERR(ts->rtask)) { - ret = 0; - } else { - free_irq(ts->ucb->irq_base + UCB_IRQ_TSPX, ts); - ts->rtask = NULL; - ret = -EFAULT; - } - - out: - return ret; -} - -/* - * Release touchscreen resources. Disable IRQs. - */ -static void ucb1x00_ts_close(struct input_dev *idev) -{ - struct ucb1x00_ts *ts = input_get_drvdata(idev); - - if (ts->rtask) - kthread_stop(ts->rtask); - - ucb1x00_enable(ts->ucb); - free_irq(ts->ucb->irq_base + UCB_IRQ_TSPX, ts); - ucb1x00_reg_write(ts->ucb, UCB_TS_CR, 0); - ucb1x00_disable(ts->ucb); -} - - -/* - * Initialisation. - */ -static int ucb1x00_ts_add(struct ucb1x00_dev *dev) -{ - struct ucb1x00_ts *ts; - struct input_dev *idev; - int err; - - ts = kzalloc_obj(struct ucb1x00_ts); - idev = input_allocate_device(); - if (!ts || !idev) { - err = -ENOMEM; - goto fail; - } - - ts->ucb = dev->ucb; - ts->idev = idev; - ts->adcsync = adcsync ? UCB_SYNC : UCB_NOSYNC; - spin_lock_init(&ts->irq_lock); - - idev->name = "Touchscreen panel"; - idev->id.product = ts->ucb->id; - idev->open = ucb1x00_ts_open; - idev->close = ucb1x00_ts_close; - idev->dev.parent = &ts->ucb->dev; - - idev->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY); - idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); - - input_set_drvdata(idev, ts); - - ucb1x00_adc_enable(ts->ucb); - ts->x_res = ucb1x00_ts_read_xres(ts); - ts->y_res = ucb1x00_ts_read_yres(ts); - ucb1x00_adc_disable(ts->ucb); - - input_set_abs_params(idev, ABS_X, 0, ts->x_res, 0, 0); - input_set_abs_params(idev, ABS_Y, 0, ts->y_res, 0, 0); - input_set_abs_params(idev, ABS_PRESSURE, 0, 0, 0, 0); - - err = input_register_device(idev); - if (err) - goto fail; - - dev->priv = ts; - - return 0; - - fail: - input_free_device(idev); - kfree(ts); - return err; -} - -static void ucb1x00_ts_remove(struct ucb1x00_dev *dev) -{ - struct ucb1x00_ts *ts = dev->priv; - - input_unregister_device(ts->idev); - kfree(ts); -} - -static struct ucb1x00_driver ucb1x00_ts_driver = { - .add = ucb1x00_ts_add, - .remove = ucb1x00_ts_remove, -}; - -static int __init ucb1x00_ts_init(void) -{ - return ucb1x00_register_driver(&ucb1x00_ts_driver); -} - -static void __exit ucb1x00_ts_exit(void) -{ - ucb1x00_unregister_driver(&ucb1x00_ts_driver); -} - -module_param(adcsync, int, 0444); -module_init(ucb1x00_ts_init); -module_exit(ucb1x00_ts_exit); - -MODULE_AUTHOR("Russell King "); -MODULE_DESCRIPTION("UCB1x00 touchscreen driver"); -MODULE_LICENSE("GPL"); diff --git a/include/linux/mfd/mcp.h b/include/linux/mfd/mcp.h deleted file mode 100644 index fd5cafc77e8a..000000000000 --- a/include/linux/mfd/mcp.h +++ /dev/null @@ -1,63 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * linux/drivers/mfd/mcp.h - * - * Copyright (C) 2001 Russell King, All Rights Reserved. - */ -#ifndef MCP_H -#define MCP_H - -#include - -struct mcp_ops; - -struct mcp { - struct module *owner; - struct mcp_ops *ops; - spinlock_t lock; - int use_count; - unsigned int sclk_rate; - unsigned int rw_timeout; - struct device attached_device; -}; - -struct mcp_ops { - void (*set_telecom_divisor)(struct mcp *, unsigned int); - void (*set_audio_divisor)(struct mcp *, unsigned int); - void (*reg_write)(struct mcp *, unsigned int, unsigned int); - unsigned int (*reg_read)(struct mcp *, unsigned int); - void (*enable)(struct mcp *); - void (*disable)(struct mcp *); -}; - -void mcp_set_telecom_divisor(struct mcp *, unsigned int); -void mcp_set_audio_divisor(struct mcp *, unsigned int); -void mcp_reg_write(struct mcp *, unsigned int, unsigned int); -unsigned int mcp_reg_read(struct mcp *, unsigned int); -void mcp_enable(struct mcp *); -void mcp_disable(struct mcp *); -#define mcp_get_sclk_rate(mcp) ((mcp)->sclk_rate) - -struct mcp *mcp_host_alloc(struct device *, size_t); -int mcp_host_add(struct mcp *, void *); -void mcp_host_del(struct mcp *); -void mcp_host_free(struct mcp *); - -struct mcp_driver { - struct device_driver drv; - int (*probe)(struct mcp *); - void (*remove)(struct mcp *); -}; - -int mcp_driver_register(struct mcp_driver *); -void mcp_driver_unregister(struct mcp_driver *); - -#define mcp_get_drvdata(mcp) dev_get_drvdata(&(mcp)->attached_device) -#define mcp_set_drvdata(mcp,d) dev_set_drvdata(&(mcp)->attached_device, d) - -static inline void *mcp_priv(struct mcp *mcp) -{ - return mcp + 1; -} - -#endif diff --git a/include/linux/mfd/ucb1x00.h b/include/linux/mfd/ucb1x00.h deleted file mode 100644 index 66ecad4667c9..000000000000 --- a/include/linux/mfd/ucb1x00.h +++ /dev/null @@ -1,261 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * linux/include/mfd/ucb1x00.h - * - * Copyright (C) 2001 Russell King, All Rights Reserved. - */ -#ifndef UCB1200_H -#define UCB1200_H - -#include -#include -#include -#include -#include - -#define UCB_IO_DATA 0x00 -#define UCB_IO_DIR 0x01 - -#define UCB_IO_0 (1 << 0) -#define UCB_IO_1 (1 << 1) -#define UCB_IO_2 (1 << 2) -#define UCB_IO_3 (1 << 3) -#define UCB_IO_4 (1 << 4) -#define UCB_IO_5 (1 << 5) -#define UCB_IO_6 (1 << 6) -#define UCB_IO_7 (1 << 7) -#define UCB_IO_8 (1 << 8) -#define UCB_IO_9 (1 << 9) - -#define UCB_IE_RIS 0x02 -#define UCB_IE_FAL 0x03 -#define UCB_IE_STATUS 0x04 -#define UCB_IE_CLEAR 0x04 -#define UCB_IE_ADC (1 << 11) -#define UCB_IE_TSPX (1 << 12) -#define UCB_IE_TSMX (1 << 13) -#define UCB_IE_TCLIP (1 << 14) -#define UCB_IE_ACLIP (1 << 15) - -#define UCB_IRQ_TSPX 12 - -#define UCB_TC_A 0x05 -#define UCB_TC_A_LOOP (1 << 7) /* UCB1200 */ -#define UCB_TC_A_AMPL (1 << 7) /* UCB1300 */ - -#define UCB_TC_B 0x06 -#define UCB_TC_B_VOICE_ENA (1 << 3) -#define UCB_TC_B_CLIP (1 << 4) -#define UCB_TC_B_ATT (1 << 6) -#define UCB_TC_B_SIDE_ENA (1 << 11) -#define UCB_TC_B_MUTE (1 << 13) -#define UCB_TC_B_IN_ENA (1 << 14) -#define UCB_TC_B_OUT_ENA (1 << 15) - -#define UCB_AC_A 0x07 -#define UCB_AC_B 0x08 -#define UCB_AC_B_LOOP (1 << 8) -#define UCB_AC_B_MUTE (1 << 13) -#define UCB_AC_B_IN_ENA (1 << 14) -#define UCB_AC_B_OUT_ENA (1 << 15) - -#define UCB_TS_CR 0x09 -#define UCB_TS_CR_TSMX_POW (1 << 0) -#define UCB_TS_CR_TSPX_POW (1 << 1) -#define UCB_TS_CR_TSMY_POW (1 << 2) -#define UCB_TS_CR_TSPY_POW (1 << 3) -#define UCB_TS_CR_TSMX_GND (1 << 4) -#define UCB_TS_CR_TSPX_GND (1 << 5) -#define UCB_TS_CR_TSMY_GND (1 << 6) -#define UCB_TS_CR_TSPY_GND (1 << 7) -#define UCB_TS_CR_MODE_INT (0 << 8) -#define UCB_TS_CR_MODE_PRES (1 << 8) -#define UCB_TS_CR_MODE_POS (2 << 8) -#define UCB_TS_CR_BIAS_ENA (1 << 11) -#define UCB_TS_CR_TSPX_LOW (1 << 12) -#define UCB_TS_CR_TSMX_LOW (1 << 13) - -#define UCB_ADC_CR 0x0a -#define UCB_ADC_SYNC_ENA (1 << 0) -#define UCB_ADC_VREFBYP_CON (1 << 1) -#define UCB_ADC_INP_TSPX (0 << 2) -#define UCB_ADC_INP_TSMX (1 << 2) -#define UCB_ADC_INP_TSPY (2 << 2) -#define UCB_ADC_INP_TSMY (3 << 2) -#define UCB_ADC_INP_AD0 (4 << 2) -#define UCB_ADC_INP_AD1 (5 << 2) -#define UCB_ADC_INP_AD2 (6 << 2) -#define UCB_ADC_INP_AD3 (7 << 2) -#define UCB_ADC_EXT_REF (1 << 5) -#define UCB_ADC_START (1 << 7) -#define UCB_ADC_ENA (1 << 15) - -#define UCB_ADC_DATA 0x0b -#define UCB_ADC_DAT_VAL (1 << 15) -#define UCB_ADC_DAT(x) (((x) & 0x7fe0) >> 5) - -#define UCB_ID 0x0c -#define UCB_ID_1200 0x1004 -#define UCB_ID_1300 0x1005 -#define UCB_ID_TC35143 0x9712 - -#define UCB_MODE 0x0d -#define UCB_MODE_DYN_VFLAG_ENA (1 << 12) -#define UCB_MODE_AUD_OFF_CAN (1 << 13) - -struct software_node; -extern const struct software_node ucb1x00_gpiochip_node; - -enum ucb1x00_reset { - UCB_RST_PROBE, - UCB_RST_RESUME, - UCB_RST_SUSPEND, - UCB_RST_REMOVE, - UCB_RST_PROBE_FAIL, -}; - -struct ucb1x00_plat_data { - void (*reset)(enum ucb1x00_reset); - unsigned irq_base; - int gpio_base; - unsigned can_wakeup; -}; - -struct ucb1x00 { - raw_spinlock_t irq_lock; - struct mcp *mcp; - unsigned int irq; - int irq_base; - struct mutex adc_mutex; - spinlock_t io_lock; - u16 id; - u16 io_dir; - u16 io_out; - u16 adc_cr; - u16 irq_fal_enbl; - u16 irq_ris_enbl; - u16 irq_mask; - u16 irq_wake; - struct device dev; - struct list_head node; - struct list_head devs; - struct gpio_chip gpio; -}; - -struct ucb1x00_driver; - -struct ucb1x00_dev { - struct list_head dev_node; - struct list_head drv_node; - struct ucb1x00 *ucb; - struct ucb1x00_driver *drv; - void *priv; -}; - -struct ucb1x00_driver { - struct list_head node; - struct list_head devs; - int (*add)(struct ucb1x00_dev *dev); - void (*remove)(struct ucb1x00_dev *dev); - int (*suspend)(struct ucb1x00_dev *dev); - int (*resume)(struct ucb1x00_dev *dev); -}; - -#define classdev_to_ucb1x00(cd) container_of(cd, struct ucb1x00, dev) - -int ucb1x00_register_driver(struct ucb1x00_driver *); -void ucb1x00_unregister_driver(struct ucb1x00_driver *); - -/** - * ucb1x00_clkrate - return the UCB1x00 SIB clock rate - * @ucb: UCB1x00 structure describing chip - * - * Return the SIB clock rate in Hz. - */ -static inline unsigned int ucb1x00_clkrate(struct ucb1x00 *ucb) -{ - return mcp_get_sclk_rate(ucb->mcp); -} - -/** - * ucb1x00_enable - enable the UCB1x00 SIB clock - * @ucb: UCB1x00 structure describing chip - * - * Enable the SIB clock. This can be called multiple times. - */ -static inline void ucb1x00_enable(struct ucb1x00 *ucb) -{ - mcp_enable(ucb->mcp); -} - -/** - * ucb1x00_disable - disable the UCB1x00 SIB clock - * @ucb: UCB1x00 structure describing chip - * - * Disable the SIB clock. The SIB clock will only be disabled - * when the number of ucb1x00_enable calls match the number of - * ucb1x00_disable calls. - */ -static inline void ucb1x00_disable(struct ucb1x00 *ucb) -{ - mcp_disable(ucb->mcp); -} - -/** - * ucb1x00_reg_write - write a UCB1x00 register - * @ucb: UCB1x00 structure describing chip - * @reg: UCB1x00 4-bit register index to write - * @val: UCB1x00 16-bit value to write - * - * Write the UCB1x00 register @reg with value @val. The SIB - * clock must be running for this function to return. - */ -static inline void ucb1x00_reg_write(struct ucb1x00 *ucb, unsigned int reg, unsigned int val) -{ - mcp_reg_write(ucb->mcp, reg, val); -} - -/** - * ucb1x00_reg_read - read a UCB1x00 register - * @ucb: UCB1x00 structure describing chip - * @reg: UCB1x00 4-bit register index to write - * - * Read the UCB1x00 register @reg and return its value. The SIB - * clock must be running for this function to return. - */ -static inline unsigned int ucb1x00_reg_read(struct ucb1x00 *ucb, unsigned int reg) -{ - return mcp_reg_read(ucb->mcp, reg); -} -/** - * ucb1x00_set_audio_divisor - - * @ucb: UCB1x00 structure describing chip - * @div: SIB clock divisor - */ -static inline void ucb1x00_set_audio_divisor(struct ucb1x00 *ucb, unsigned int div) -{ - mcp_set_audio_divisor(ucb->mcp, div); -} - -/** - * ucb1x00_set_telecom_divisor - - * @ucb: UCB1x00 structure describing chip - * @div: SIB clock divisor - */ -static inline void ucb1x00_set_telecom_divisor(struct ucb1x00 *ucb, unsigned int div) -{ - mcp_set_telecom_divisor(ucb->mcp, div); -} - -void ucb1x00_io_set_dir(struct ucb1x00 *ucb, unsigned int, unsigned int); -void ucb1x00_io_write(struct ucb1x00 *ucb, unsigned int, unsigned int); -unsigned int ucb1x00_io_read(struct ucb1x00 *ucb); - -#define UCB_NOSYNC (0) -#define UCB_SYNC (1) - -unsigned int ucb1x00_adc_read(struct ucb1x00 *ucb, int adc_channel, int sync); -void ucb1x00_adc_enable(struct ucb1x00 *ucb); -void ucb1x00_adc_disable(struct ucb1x00 *ucb); - -#endif diff --git a/include/linux/platform_data/mfd-mcp-sa11x0.h b/include/linux/platform_data/mfd-mcp-sa11x0.h deleted file mode 100644 index b589e61bbc2e..000000000000 --- a/include/linux/platform_data/mfd-mcp-sa11x0.h +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) 2005 Russell King. - */ -#ifndef __MFD_MCP_SA11X0_H -#define __MFD_MCP_SA11X0_H - -#include - -struct mcp_plat_data { - u32 mccr0; - u32 mccr1; - unsigned int sclk_rate; - void *codec_pdata; -}; - -#endif -- 2.53.0