From patchwork Tue Jun 14 02:17:51 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chen-Yu Tsai X-Patchwork-Id: 635002 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from mail-oi0-x238.google.com (mail-oi0-x238.google.com [IPv6:2607:f8b0:4003:c06::238]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3rTCx7062jz9t18 for ; Tue, 14 Jun 2016 12:18:19 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=googlegroups.com header.i=@googlegroups.com header.b=WsPaLGDE; dkim-atps=neutral Received: by mail-oi0-x238.google.com with SMTP id f189sf17706419oig.1 for ; Mon, 13 Jun 2016 19:18:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlegroups.com; s=20120806; h=sender:mime-version:from:to:cc:subject:date:message-id:in-reply-to :references:x-original-sender:x-original-authentication-results :reply-to:precedence:mailing-list:list-id:x-spam-checked-in-group :list-post:list-help:list-archive:list-subscribe:list-unsubscribe; bh=zVasVYGEyjPfW/LqtxgoMUCke5TRncoFMKP3amv6JmI=; b=WsPaLGDEG/ozr0PHdjOcIy0emCXetIRhjBxEx8w7yp1XEOORw+P/Hd1dy9shGyHP1j K6huo3k9Ik5+my1QISsNYZTlg2nUgA5gao29gSHFpdlqpMHGsE3Q7aVCb6ZcRY6g3LqX /deE3SmPR9sV2N2QP4u24ypX8bJ/GhsDozsBeKPJtrzUKuLiph85DzFr84oUdN41mYVg dZCIXUBPIr0vIMyzq1MbhKF+jNV1hfC2JDem+4VAcHDPYO6vjjDy1rugElejE5FuVP3V PMzX7y5XLNjc5NrwHASCqMzT6w3iyWN+4pTOiRHbNqfhOpBhkyLfeaJVxEUH9hOvhDbC oHAg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=sender:x-gm-message-state:mime-version:from:to:cc:subject:date :message-id:in-reply-to:references:x-original-sender :x-original-authentication-results:reply-to:precedence:mailing-list :list-id:x-spam-checked-in-group:list-post:list-help:list-archive :list-subscribe:list-unsubscribe; bh=zVasVYGEyjPfW/LqtxgoMUCke5TRncoFMKP3amv6JmI=; b=b/cZjw1VESi6AcMmsflbLMHOPWkRBxsLWmnZO4GxEreZmNdK4/xjGGo/3DLRSG77tj NEzfvhUbOgGZs6QrxmMdDJwppT0jO4uYQkNgcl0JuYxZ5qHlbbvURw6QeX8/6cbqUliu ZQ6EQ6Q0gO5kEn/OyPPDMC013xyQKT8dqRYFA9PmhvYZDn+JULtiA5wAqhqTMAD4oUdO NjRbw/xyL6tU/cZF0FyukDEJ7bmyUtHQJSxVCgQ9bJuUAhjmpWaSYk6aIqxdglUhzYyw eUjpWhy51h1IzF/zIgA3r774u69wJYLvcxGuT2CA3DX983f53qRKeZf5TB9lQO80INGb pVAg== Sender: rtc-linux@googlegroups.com X-Gm-Message-State: ALyK8tIHrLinHqJXUrmWUXzxnxpcj8YzRDeR08mtAd9fFDvp+DuE15U3Rhh3McTaeeQpvw== X-Received: by 10.140.21.134 with SMTP id 6mr579634qgl.20.1465870696931; Mon, 13 Jun 2016 19:18:16 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: rtc-linux@googlegroups.com Received: by 10.140.92.145 with SMTP id b17ls1663729qge.1.gmail; Mon, 13 Jun 2016 19:18:16 -0700 (PDT) X-Received: by 10.176.1.73 with SMTP id 67mr14694323uak.8.1465870696646; Mon, 13 Jun 2016 19:18:16 -0700 (PDT) Received: from wens.csie.org (mirror2.csie.ntu.edu.tw. [140.112.30.76]) by gmr-mx.google.com with ESMTPS id un17si691257pab.0.2016.06.13.19.18.16 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 13 Jun 2016 19:18:16 -0700 (PDT) Received-SPF: neutral (google.com: 140.112.30.76 is neither permitted nor denied by best guess record for domain of wens@wens.csie.org) client-ip=140.112.30.76; Received: by wens.csie.org (Postfix, from userid 1000) id 75A7C5F999; Tue, 14 Jun 2016 10:18:13 +0800 (CST) From: Chen-Yu Tsai To: Mark Brown , Lee Jones , Alessandro Zummo , Alexandre Belloni , Rob Herring , Pawel Moll , Mark Rutland , Ian Campbell , Kumar Gala , Maxime Ripard , Michael Turquette , Stephen Boyd Cc: Chen-Yu Tsai , rtc-linux@googlegroups.com, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-clk@vger.kernel.org Subject: [rtc-linux] [PATCH 03/10] mfd: Add driver for X-Powers AC100 audio codec / RTC combo IC Date: Tue, 14 Jun 2016 10:17:51 +0800 Message-Id: <1465870678-30128-5-git-send-email-wens@csie.org> X-Mailer: git-send-email 2.8.1 In-Reply-To: <1465870678-30128-1-git-send-email-wens@csie.org> References: <1465870678-30128-1-git-send-email-wens@csie.org> X-Original-Sender: wens@csie.org X-Original-Authentication-Results: gmr-mx.google.com; spf=neutral (google.com: 140.112.30.76 is neither permitted nor denied by best guess record for domain of wens@wens.csie.org) smtp.mailfrom=wens@wens.csie.org Reply-To: rtc-linux@googlegroups.com Precedence: list Mailing-list: list rtc-linux@googlegroups.com; contact rtc-linux+owners@googlegroups.com List-ID: X-Spam-Checked-In-Group: rtc-linux@googlegroups.com X-Google-Group-Id: 712029733259 List-Post: , List-Help: , List-Archive: , List-Unsubscribe: , The AC100 is a multifunction device with an audio codec subsystem and an RTC subsystem. These two subsystems share a common register space and host interface. Signed-off-by: Chen-Yu Tsai --- drivers/mfd/Kconfig | 10 ++++ drivers/mfd/Makefile | 2 + drivers/mfd/ac100.c | 116 ++++++++++++++++++++++++++++++++++++++++++++++ include/linux/mfd/ac100.h | 62 +++++++++++++++++++++++++ 4 files changed, 190 insertions(+) create mode 100644 drivers/mfd/ac100.c create mode 100644 include/linux/mfd/ac100.h diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 1bcf601de5bc..bd83849a0c8d 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -101,6 +101,16 @@ config MFD_BCM590XX help Support for the BCM590xx PMUs from Broadcom +config MFD_AC100 + tristate "X-Powers AC100" + select MFD_CORE + depends on SUNXI_RSB + help + If you say Y here you get support for the X-Powers AC100 audio codec + IC. + This driver include only the core APIs. You have to select individual + components like codecs or RTC under the corresponding menus. + config MFD_AXP20X tristate select MFD_CORE diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 42a66e19e191..60f9a6b0557c 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -113,6 +113,8 @@ obj-$(CONFIG_PMIC_DA9052) += da9052-irq.o obj-$(CONFIG_PMIC_DA9052) += da9052-core.o obj-$(CONFIG_MFD_DA9052_SPI) += da9052-spi.o obj-$(CONFIG_MFD_DA9052_I2C) += da9052-i2c.o + +obj-$(CONFIG_MFD_AC100) += ac100.o obj-$(CONFIG_MFD_AXP20X) += axp20x.o obj-$(CONFIG_MFD_AXP20X_I2C) += axp20x-i2c.o obj-$(CONFIG_MFD_AXP20X_RSB) += axp20x-rsb.o diff --git a/drivers/mfd/ac100.c b/drivers/mfd/ac100.c new file mode 100644 index 000000000000..3e6752e9dc07 --- /dev/null +++ b/drivers/mfd/ac100.c @@ -0,0 +1,116 @@ +/* + * ac100.c - MFD core driver for X-Powers' AC100 Audio Codec IC + * + * The AC100 is a highly integrated audio codec and RTC subsystem designed + * for mobile applications. It has 3 I2S/PCM interfaces, a 2 channel DAC, + * a 2 channel ADC with 5 inputs and a builtin mixer. The RTC subsystem has + * 3 clock outputs. + * + * The audio codec and RTC parts are completely separate, sharing only the + * host interface for access to its registers. + * + * Author: Chen-Yu Tsai + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static const struct regmap_range ac100_writeable_ranges[] = { + regmap_reg_range(AC100_CLK32K_ANALOG_CTRL, AC100_CLK32K_OUT_CTRL3), + regmap_reg_range(AC100_RTC_RST, AC100_RTC_UPD), + regmap_reg_range(AC100_ALM_INT_ENA, AC100_ALM_INT_STA), + regmap_reg_range(AC100_ALM_SEC, AC100_RTC_GP(15)), +}; + +static const struct regmap_range ac100_volatile_ranges[] = { + regmap_reg_range(AC100_RTC_RST, AC100_RTC_RST), + regmap_reg_range(AC100_RTC_SEC, AC100_ALM_INT_STA), + regmap_reg_range(AC100_ALM_SEC, AC100_ALM_UPD), +}; + +static const struct regmap_access_table ac100_writeable_table = { + .yes_ranges = ac100_writeable_ranges, + .n_yes_ranges = ARRAY_SIZE(ac100_writeable_ranges), +}; + +static const struct regmap_access_table ac100_volatile_table = { + .yes_ranges = ac100_volatile_ranges, + .n_yes_ranges = ARRAY_SIZE(ac100_volatile_ranges), +}; + +static const struct regmap_config ac100_regmap_config = { + .reg_bits = 8, + .val_bits = 16, + .wr_table = &ac100_writeable_table, + .volatile_table = &ac100_volatile_table, + .max_register = AC100_RTC_GP(15), + .cache_type = REGCACHE_RBTREE, +}; + +static struct mfd_cell ac100_cells[] = { + { + .name = "ac100-codec", + .of_compatible = "x-powers,ac100-codec", + }, { + .name = "ac100-rtc", + .of_compatible = "x-powers,ac100-rtc", + }, +}; + +static int ac100_rsb_probe(struct sunxi_rsb_device *rdev) +{ + struct ac100_dev *ac100; + int ret; + + ac100 = devm_kzalloc(&rdev->dev, sizeof(*ac100), GFP_KERNEL); + if (!ac100) + return -ENOMEM; + + ac100->dev = &rdev->dev; + sunxi_rsb_device_set_drvdata(rdev, ac100); + + ac100->regmap = devm_regmap_init_sunxi_rsb(rdev, &ac100_regmap_config); + if (IS_ERR(ac100->regmap)) { + ret = PTR_ERR(ac100->regmap); + dev_err(ac100->dev, "regmap init failed: %d\n", ret); + return ret; + } + + ret = devm_mfd_add_devices(ac100->dev, PLATFORM_DEVID_NONE, ac100_cells, + ARRAY_SIZE(ac100_cells), NULL, 0, NULL); + if (ret) { + dev_err(ac100->dev, "failed to add MFD devices: %d\n", ret); + return ret; + } + + return 0; +} + +static const struct of_device_id ac100_of_match[] = { + { .compatible = "x-powers,ac100" }, + { }, +}; +MODULE_DEVICE_TABLE(of, ac100_of_match); + +static struct sunxi_rsb_driver ac100_rsb_driver = { + .driver = { + .name = "ac100", + .of_match_table = of_match_ptr(ac100_of_match), + }, + .probe = ac100_rsb_probe, +}; +module_sunxi_rsb_driver(ac100_rsb_driver); + +MODULE_DESCRIPTION("Audio codec MFD core driver for AC100"); +MODULE_AUTHOR("Chen-Yu Tsai "); +MODULE_LICENSE("GPL"); diff --git a/include/linux/mfd/ac100.h b/include/linux/mfd/ac100.h new file mode 100644 index 000000000000..6d3b9f5c5aa2 --- /dev/null +++ b/include/linux/mfd/ac100.h @@ -0,0 +1,62 @@ +/* + * Functions and registers to access AC100 codec / RTC combo IC. + * + * Copyright (C) 2013, Carlo Caione + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __LINUX_MFD_AC100_H +#define __LINUX_MFD_AC100_H + +#include + +struct ac100_dev { + struct device *dev; + struct regmap *regmap; +}; + +/* Audio codec related registers */ +#define AC100_AUDIO_CHIP_RST 0x00 +#define AC100_PLL_CTRL1 0x01 +#define AC100_PLL_CTRL2 0x02 +#define AC100_SYSCLK_CTRL 0x03 +#define AC100_MOD_CLK_ENA 0x04 +#define AC100_MOD_RST_CTRL 0x05 + +/* RTC */ +#define AC100_CLK32K_ANALOG_CTRL 0xc0 +#define AC100_CLK32K_OUT_CTRL1 0xc1 +#define AC100_CLK32K_OUT_CTRL2 0xc2 +#define AC100_CLK32K_OUT_CTRL3 0xc3 + +/* RTC module */ +#define AC100_RTC_RST 0xc6 +#define AC100_RTC_CTRL 0xc7 +#define AC100_RTC_SEC 0xc8 /* second */ +#define AC100_RTC_MIN 0xc9 /* minute */ +#define AC100_RTC_HOU 0xca /* hour */ +#define AC100_RTC_WEE 0xcb /* weekday */ +#define AC100_RTC_DAY 0xcc /* day */ +#define AC100_RTC_MON 0xcd /* month */ +#define AC100_RTC_YEA 0xce /* year */ +#define AC100_RTC_UPD 0xcf /* update trigger */ + +/* RTC Alarm */ +#define AC100_ALM_INT_ENA 0xd0 +#define AC100_ALM_INT_STA 0xd1 +#define AC100_ALM_SEC 0xd8 +#define AC100_ALM_MIN 0xd9 +#define AC100_ALM_HOU 0xda +#define AC100_ALM_WEE 0xdb +#define AC100_ALM_DAY 0xdc +#define AC100_ALM_MON 0xdd +#define AC100_ALM_YEA 0xde +#define AC100_ALM_UPD 0xdf + +/* RTC general purpose register 0 ~ 15 */ +#define AC100_RTC_GP(x) (0xe0 + (x)) + +#endif /* __LINUX_MFD_AC100_H */