mirror of
https://github.com/Fishwaldo/build.git
synced 2025-07-22 21:08:49 +00:00
Move sunxi/64 current to 5.7, legacy to 5.4 (#2098)
* Move sunxi/64 current to 5.7, legacy to 5.4 * Update sunxidev config
This commit is contained in:
parent
812245def3
commit
caa47bad65
430 changed files with 20432 additions and 75488 deletions
440
patch/kernel/sunxi-current/0001-mfd-Add-support-for-AC200.patch
Normal file
440
patch/kernel/sunxi-current/0001-mfd-Add-support-for-AC200.patch
Normal file
|
@ -0,0 +1,440 @@
|
|||
From d98aa318aabd4aba05328f9c832b23bdf2e1677a Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Fri, 16 Aug 2019 16:38:21 +0200
|
||||
Subject: [PATCH 1/4] mfd: Add support for AC200
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
drivers/mfd/Kconfig | 9 ++
|
||||
drivers/mfd/Makefile | 1 +
|
||||
drivers/mfd/ac200.c | 170 +++++++++++++++++++++++++++++++
|
||||
include/linux/mfd/ac200.h | 208 ++++++++++++++++++++++++++++++++++++++
|
||||
4 files changed, 388 insertions(+)
|
||||
create mode 100644 drivers/mfd/ac200.c
|
||||
create mode 100644 include/linux/mfd/ac200.h
|
||||
|
||||
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
|
||||
index 420900852166..a45e7c88ac9b 100644
|
||||
--- a/drivers/mfd/Kconfig
|
||||
+++ b/drivers/mfd/Kconfig
|
||||
@@ -178,6 +178,15 @@ config MFD_AC100
|
||||
This driver include only the core APIs. You have to select individual
|
||||
components like codecs or RTC under the corresponding menus.
|
||||
|
||||
+config MFD_AC200
|
||||
+ tristate "X-Powers AC200"
|
||||
+ select MFD_CORE
|
||||
+ depends on I2C
|
||||
+ help
|
||||
+ If you say Y here you get support for the X-Powers AC200 IC.
|
||||
+ This driver include only the core APIs. You have to select individual
|
||||
+ components like Ethernet PHY or RTC under the corresponding menus.
|
||||
+
|
||||
config MFD_AXP20X
|
||||
tristate
|
||||
select MFD_CORE
|
||||
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
|
||||
index aed99f08739f..4431a4cf19ca 100644
|
||||
--- a/drivers/mfd/Makefile
|
||||
+++ b/drivers/mfd/Makefile
|
||||
@@ -141,6 +141,7 @@ 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_AC200) += ac200.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/ac200.c b/drivers/mfd/ac200.c
|
||||
new file mode 100644
|
||||
index 000000000000..570573790d91
|
||||
--- /dev/null
|
||||
+++ b/drivers/mfd/ac200.c
|
||||
@@ -0,0 +1,170 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-only
|
||||
+/*
|
||||
+ * MFD core driver for X-Powers' AC200 IC
|
||||
+ *
|
||||
+ * The AC200 is a chip which is co-packaged with Allwinner H6 SoC and
|
||||
+ * includes analog audio codec, analog TV encoder, ethernet PHY, eFuse
|
||||
+ * and RTC.
|
||||
+ *
|
||||
+ * Copyright (c) 2020 Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/i2c.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/mfd/core.h>
|
||||
+#include <linux/mfd/ac200.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of.h>
|
||||
+
|
||||
+/* Interrupts */
|
||||
+#define AC200_IRQ_RTC 0
|
||||
+#define AC200_IRQ_EPHY 1
|
||||
+#define AC200_IRQ_TVE 2
|
||||
+
|
||||
+/* IRQ enable register */
|
||||
+#define AC200_SYS_IRQ_ENABLE_OUT_EN BIT(15)
|
||||
+#define AC200_SYS_IRQ_ENABLE_RTC BIT(12)
|
||||
+#define AC200_SYS_IRQ_ENABLE_EPHY BIT(8)
|
||||
+#define AC200_SYS_IRQ_ENABLE_TVE BIT(4)
|
||||
+
|
||||
+static const struct regmap_range_cfg ac200_range_cfg[] = {
|
||||
+ {
|
||||
+ .range_min = AC200_SYS_VERSION,
|
||||
+ .range_max = AC200_IC_CHARA1,
|
||||
+ .selector_reg = AC200_TWI_REG_ADDR_H,
|
||||
+ .selector_mask = 0xff,
|
||||
+ .selector_shift = 0,
|
||||
+ .window_start = 0,
|
||||
+ .window_len = 256,
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+static const struct regmap_config ac200_regmap_config = {
|
||||
+ .reg_bits = 8,
|
||||
+ .val_bits = 16,
|
||||
+ .ranges = ac200_range_cfg,
|
||||
+ .num_ranges = ARRAY_SIZE(ac200_range_cfg),
|
||||
+ .max_register = AC200_IC_CHARA1,
|
||||
+};
|
||||
+
|
||||
+static const struct regmap_irq ac200_regmap_irqs[] = {
|
||||
+ REGMAP_IRQ_REG(AC200_IRQ_RTC, 0, AC200_SYS_IRQ_ENABLE_RTC),
|
||||
+ REGMAP_IRQ_REG(AC200_IRQ_EPHY, 0, AC200_SYS_IRQ_ENABLE_EPHY),
|
||||
+ REGMAP_IRQ_REG(AC200_IRQ_TVE, 0, AC200_SYS_IRQ_ENABLE_TVE),
|
||||
+};
|
||||
+
|
||||
+static const struct regmap_irq_chip ac200_regmap_irq_chip = {
|
||||
+ .name = "ac200_irq_chip",
|
||||
+ .status_base = AC200_SYS_IRQ_STATUS,
|
||||
+ .mask_base = AC200_SYS_IRQ_ENABLE,
|
||||
+ .mask_invert = true,
|
||||
+ .irqs = ac200_regmap_irqs,
|
||||
+ .num_irqs = ARRAY_SIZE(ac200_regmap_irqs),
|
||||
+ .num_regs = 1,
|
||||
+};
|
||||
+
|
||||
+static const struct resource ephy_resource[] = {
|
||||
+ DEFINE_RES_IRQ(AC200_IRQ_EPHY),
|
||||
+};
|
||||
+
|
||||
+static const struct mfd_cell ac200_cells[] = {
|
||||
+ {
|
||||
+ .name = "ac200-ephy",
|
||||
+ .num_resources = ARRAY_SIZE(ephy_resource),
|
||||
+ .resources = ephy_resource,
|
||||
+ .of_compatible = "x-powers,ac200-ephy",
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int ac200_i2c_probe(struct i2c_client *i2c,
|
||||
+ const struct i2c_device_id *id)
|
||||
+{
|
||||
+ struct device *dev = &i2c->dev;
|
||||
+ struct ac200_dev *ac200;
|
||||
+ int ret;
|
||||
+
|
||||
+ ac200 = devm_kzalloc(dev, sizeof(*ac200), GFP_KERNEL);
|
||||
+ if (!ac200)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ i2c_set_clientdata(i2c, ac200);
|
||||
+
|
||||
+ ac200->regmap = devm_regmap_init_i2c(i2c, &ac200_regmap_config);
|
||||
+ if (IS_ERR(ac200->regmap)) {
|
||||
+ ret = PTR_ERR(ac200->regmap);
|
||||
+ dev_err(dev, "regmap init failed: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /* do a reset to put chip in a known state */
|
||||
+
|
||||
+ ret = regmap_write(ac200->regmap, AC200_SYS_CONTROL, 0);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = regmap_write(ac200->regmap, AC200_SYS_CONTROL, 1);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* enable interrupt pin */
|
||||
+
|
||||
+ ret = regmap_write(ac200->regmap, AC200_SYS_IRQ_ENABLE,
|
||||
+ AC200_SYS_IRQ_ENABLE_OUT_EN);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = regmap_add_irq_chip(ac200->regmap, i2c->irq, IRQF_ONESHOT, 0,
|
||||
+ &ac200_regmap_irq_chip, &ac200->regmap_irqc);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, ac200_cells,
|
||||
+ ARRAY_SIZE(ac200_cells), NULL, 0, NULL);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "failed to add MFD devices: %d\n", ret);
|
||||
+ regmap_del_irq_chip(i2c->irq, ac200->regmap_irqc);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int ac200_i2c_remove(struct i2c_client *i2c)
|
||||
+{
|
||||
+ struct ac200_dev *ac200 = i2c_get_clientdata(i2c);
|
||||
+
|
||||
+ regmap_write(ac200->regmap, AC200_SYS_CONTROL, 0);
|
||||
+
|
||||
+ mfd_remove_devices(&i2c->dev);
|
||||
+ regmap_del_irq_chip(i2c->irq, ac200->regmap_irqc);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct i2c_device_id ac200_ids[] = {
|
||||
+ { "ac200", },
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(i2c, ac200_ids);
|
||||
+
|
||||
+static const struct of_device_id ac200_of_match[] = {
|
||||
+ { .compatible = "x-powers,ac200" },
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, ac200_of_match);
|
||||
+
|
||||
+static struct i2c_driver ac200_i2c_driver = {
|
||||
+ .driver = {
|
||||
+ .name = "ac200",
|
||||
+ .of_match_table = of_match_ptr(ac200_of_match),
|
||||
+ },
|
||||
+ .probe = ac200_i2c_probe,
|
||||
+ .remove = ac200_i2c_remove,
|
||||
+ .id_table = ac200_ids,
|
||||
+};
|
||||
+module_i2c_driver(ac200_i2c_driver);
|
||||
+
|
||||
+MODULE_DESCRIPTION("MFD core driver for AC200");
|
||||
+MODULE_AUTHOR("Jernej Skrabec <jernej.skrabec@siol.net>");
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
diff --git a/include/linux/mfd/ac200.h b/include/linux/mfd/ac200.h
|
||||
new file mode 100644
|
||||
index 000000000000..0c677094a5b3
|
||||
--- /dev/null
|
||||
+++ b/include/linux/mfd/ac200.h
|
||||
@@ -0,0 +1,208 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
+/*
|
||||
+ * AC200 register list
|
||||
+ *
|
||||
+ * Copyright (C) 2019 Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
+ */
|
||||
+
|
||||
+#ifndef __LINUX_MFD_AC200_H
|
||||
+#define __LINUX_MFD_AC200_H
|
||||
+
|
||||
+#include <linux/regmap.h>
|
||||
+
|
||||
+/* interface registers (can be accessed from any page) */
|
||||
+#define AC200_TWI_CHANGE_TO_RSB 0x3E
|
||||
+#define AC200_TWI_PAD_DELAY 0xC4
|
||||
+#define AC200_TWI_REG_ADDR_H 0xFE
|
||||
+
|
||||
+/* General registers */
|
||||
+#define AC200_SYS_VERSION 0x0000
|
||||
+#define AC200_SYS_CONTROL 0x0002
|
||||
+#define AC200_SYS_IRQ_ENABLE 0x0004
|
||||
+#define AC200_SYS_IRQ_STATUS 0x0006
|
||||
+#define AC200_SYS_CLK_CTL 0x0008
|
||||
+#define AC200_SYS_DLDO_OSC_CTL 0x000A
|
||||
+#define AC200_SYS_PLL_CTL0 0x000C
|
||||
+#define AC200_SYS_PLL_CTL1 0x000E
|
||||
+#define AC200_SYS_AUDIO_CTL0 0x0010
|
||||
+#define AC200_SYS_AUDIO_CTL1 0x0012
|
||||
+#define AC200_SYS_EPHY_CTL0 0x0014
|
||||
+#define AC200_SYS_EPHY_CTL1 0x0016
|
||||
+#define AC200_SYS_TVE_CTL0 0x0018
|
||||
+#define AC200_SYS_TVE_CTL1 0x001A
|
||||
+
|
||||
+/* Audio Codec registers */
|
||||
+#define AC200_AC_SYS_CLK_CTL 0x2000
|
||||
+#define AC200_SYS_MOD_RST 0x2002
|
||||
+#define AC200_SYS_SAMP_CTL 0x2004
|
||||
+#define AC200_I2S_CTL 0x2100
|
||||
+#define AC200_I2S_CLK 0x2102
|
||||
+#define AC200_I2S_FMT0 0x2104
|
||||
+#define AC200_I2S_FMT1 0x2108
|
||||
+#define AC200_I2S_MIX_SRC 0x2114
|
||||
+#define AC200_I2S_MIX_GAIN 0x2116
|
||||
+#define AC200_I2S_DACDAT_DVC 0x2118
|
||||
+#define AC200_I2S_ADCDAT_DVC 0x211A
|
||||
+#define AC200_AC_DAC_DPC 0x2200
|
||||
+#define AC200_AC_DAC_MIX_SRC 0x2202
|
||||
+#define AC200_AC_DAC_MIX_GAIN 0x2204
|
||||
+#define AC200_DACA_OMIXER_CTRL 0x2220
|
||||
+#define AC200_OMIXER_SR 0x2222
|
||||
+#define AC200_LINEOUT_CTRL 0x2224
|
||||
+#define AC200_AC_ADC_DPC 0x2300
|
||||
+#define AC200_MBIAS_CTRL 0x2310
|
||||
+#define AC200_ADC_MIC_CTRL 0x2320
|
||||
+#define AC200_ADCMIXER_SR 0x2322
|
||||
+#define AC200_ANALOG_TUNING0 0x232A
|
||||
+#define AC200_ANALOG_TUNING1 0x232C
|
||||
+#define AC200_AC_AGC_SEL 0x2480
|
||||
+#define AC200_ADC_DAPLCTRL 0x2500
|
||||
+#define AC200_ADC_DAPRCTRL 0x2502
|
||||
+#define AC200_ADC_DAPLSTA 0x2504
|
||||
+#define AC200_ADC_DAPRSTA 0x2506
|
||||
+#define AC200_ADC_DAPLTL 0x2508
|
||||
+#define AC200_ADC_DAPRTL 0x250A
|
||||
+#define AC200_ADC_DAPLHAC 0x250C
|
||||
+#define AC200_ADC_DAPLLAC 0x250E
|
||||
+#define AC200_ADC_DAPRHAC 0x2510
|
||||
+#define AC200_ADC_DAPRLAC 0x2512
|
||||
+#define AC200_ADC_DAPLDT 0x2514
|
||||
+#define AC200_ADC_DAPLAT 0x2516
|
||||
+#define AC200_ADC_DAPRDT 0x2518
|
||||
+#define AC200_ADC_DAPRAT 0x251A
|
||||
+#define AC200_ADC_DAPNTH 0x251C
|
||||
+#define AC200_ADC_DAPLHNAC 0x251E
|
||||
+#define AC200_ADC_DAPLLNAC 0x2520
|
||||
+#define AC200_ADC_DAPRHNAC 0x2522
|
||||
+#define AC200_ADC_DAPRLNAC 0x2524
|
||||
+#define AC200_AC_DAPHHPFC 0x2526
|
||||
+#define AC200_AC_DAPLHPFC 0x2528
|
||||
+#define AC200_AC_DAPOPT 0x252A
|
||||
+#define AC200_AC_DAC_DAPCTRL 0x3000
|
||||
+#define AC200_AC_DRC_HHPFC 0x3002
|
||||
+#define AC200_AC_DRC_LHPFC 0x3004
|
||||
+#define AC200_AC_DRC_CTRL 0x3006
|
||||
+#define AC200_AC_DRC_LPFHAT 0x3008
|
||||
+#define AC200_AC_DRC_LPFLAT 0x300A
|
||||
+#define AC200_AC_DRC_RPFHAT 0x300C
|
||||
+#define AC200_AC_DRC_RPFLAT 0x300E
|
||||
+#define AC200_AC_DRC_LPFHRT 0x3010
|
||||
+#define AC200_AC_DRC_LPFLRT 0x3012
|
||||
+#define AC200_AC_DRC_RPFHRT 0x3014
|
||||
+#define AC200_AC_DRC_RPFLRT 0x3016
|
||||
+#define AC200_AC_DRC_LRMSHAT 0x3018
|
||||
+#define AC200_AC_DRC_LRMSLAT 0x301A
|
||||
+#define AC200_AC_DRC_RRMSHAT 0x301C
|
||||
+#define AC200_AC_DRC_RRMSLAT 0x301E
|
||||
+#define AC200_AC_DRC_HCT 0x3020
|
||||
+#define AC200_AC_DRC_LCT 0x3022
|
||||
+#define AC200_AC_DRC_HKC 0x3024
|
||||
+#define AC200_AC_DRC_LKC 0x3026
|
||||
+#define AC200_AC_DRC_HOPC 0x3028
|
||||
+#define AC200_AC_DRC_LOPC 0x302A
|
||||
+#define AC200_AC_DRC_HLT 0x302C
|
||||
+#define AC200_AC_DRC_LLT 0x302E
|
||||
+#define AC200_AC_DRC_HKI 0x3030
|
||||
+#define AC200_AC_DRC_LKI 0x3032
|
||||
+#define AC200_AC_DRC_HOPL 0x3034
|
||||
+#define AC200_AC_DRC_LOPL 0x3036
|
||||
+#define AC200_AC_DRC_HET 0x3038
|
||||
+#define AC200_AC_DRC_LET 0x303A
|
||||
+#define AC200_AC_DRC_HKE 0x303C
|
||||
+#define AC200_AC_DRC_LKE 0x303E
|
||||
+#define AC200_AC_DRC_HOPE 0x3040
|
||||
+#define AC200_AC_DRC_LOPE 0x3042
|
||||
+#define AC200_AC_DRC_HKN 0x3044
|
||||
+#define AC200_AC_DRC_LKN 0x3046
|
||||
+#define AC200_AC_DRC_SFHAT 0x3048
|
||||
+#define AC200_AC_DRC_SFLAT 0x304A
|
||||
+#define AC200_AC_DRC_SFHRT 0x304C
|
||||
+#define AC200_AC_DRC_SFLRT 0x304E
|
||||
+#define AC200_AC_DRC_MXGHS 0x3050
|
||||
+#define AC200_AC_DRC_MXGLS 0x3052
|
||||
+#define AC200_AC_DRC_MNGHS 0x3054
|
||||
+#define AC200_AC_DRC_MNGLS 0x3056
|
||||
+#define AC200_AC_DRC_EPSHC 0x3058
|
||||
+#define AC200_AC_DRC_EPSLC 0x305A
|
||||
+#define AC200_AC_DRC_HPFHGAIN 0x305E
|
||||
+#define AC200_AC_DRC_HPFLGAIN 0x3060
|
||||
+#define AC200_AC_DRC_BISTCR 0x3100
|
||||
+#define AC200_AC_DRC_BISTST 0x3102
|
||||
+
|
||||
+/* TVE registers */
|
||||
+#define AC200_TVE_CTL0 0x4000
|
||||
+#define AC200_TVE_CTL1 0x4002
|
||||
+#define AC200_TVE_MOD0 0x4004
|
||||
+#define AC200_TVE_MOD1 0x4006
|
||||
+#define AC200_TVE_DAC_CFG0 0x4008
|
||||
+#define AC200_TVE_DAC_CFG1 0x400A
|
||||
+#define AC200_TVE_YC_DELAY 0x400C
|
||||
+#define AC200_TVE_YC_FILTER 0x400E
|
||||
+#define AC200_TVE_BURST_FRQ0 0x4010
|
||||
+#define AC200_TVE_BURST_FRQ1 0x4012
|
||||
+#define AC200_TVE_FRONT_PORCH 0x4014
|
||||
+#define AC200_TVE_BACK_PORCH 0x4016
|
||||
+#define AC200_TVE_TOTAL_LINE 0x401C
|
||||
+#define AC200_TVE_FIRST_ACTIVE 0x401E
|
||||
+#define AC200_TVE_BLACK_LEVEL 0x4020
|
||||
+#define AC200_TVE_BLANK_LEVEL 0x4022
|
||||
+#define AC200_TVE_PLUG_EN 0x4030
|
||||
+#define AC200_TVE_PLUG_IRQ_EN 0x4032
|
||||
+#define AC200_TVE_PLUG_IRQ_STA 0x4034
|
||||
+#define AC200_TVE_PLUG_STA 0x4038
|
||||
+#define AC200_TVE_PLUG_DEBOUNCE 0x4040
|
||||
+#define AC200_TVE_DAC_TEST 0x4042
|
||||
+#define AC200_TVE_PLUG_PULSE_LEVEL 0x40F4
|
||||
+#define AC200_TVE_PLUG_PULSE_START 0x40F8
|
||||
+#define AC200_TVE_PLUG_PULSE_PERIOD 0x40FA
|
||||
+#define AC200_TVE_IF_CTL 0x5000
|
||||
+#define AC200_TVE_IF_TIM0 0x5008
|
||||
+#define AC200_TVE_IF_TIM1 0x500A
|
||||
+#define AC200_TVE_IF_TIM2 0x500C
|
||||
+#define AC200_TVE_IF_TIM3 0x500E
|
||||
+#define AC200_TVE_IF_SYNC0 0x5010
|
||||
+#define AC200_TVE_IF_SYNC1 0x5012
|
||||
+#define AC200_TVE_IF_SYNC2 0x5014
|
||||
+#define AC200_TVE_IF_TIM4 0x5016
|
||||
+#define AC200_TVE_IF_STATUS 0x5018
|
||||
+
|
||||
+/* EPHY registers */
|
||||
+#define AC200_EPHY_CTL 0x6000
|
||||
+#define AC200_EPHY_BIST 0x6002
|
||||
+
|
||||
+/* eFuse registers (0x8000 - 0x9FFF, layout unknown) */
|
||||
+
|
||||
+/* RTC registers */
|
||||
+#define AC200_LOSC_CTRL0 0xA000
|
||||
+#define AC200_LOSC_CTRL1 0xA002
|
||||
+#define AC200_LOSC_AUTO_SWT_STA 0xA004
|
||||
+#define AC200_INTOSC_CLK_PRESCAL 0xA008
|
||||
+#define AC200_RTC_YY_MM_DD0 0xA010
|
||||
+#define AC200_RTC_YY_MM_DD1 0xA012
|
||||
+#define AC200_RTC_HH_MM_SS0 0xA014
|
||||
+#define AC200_RTC_HH_MM_SS1 0xA016
|
||||
+#define AC200_ALARM0_CUR_VLU0 0xA024
|
||||
+#define AC200_ALARM0_CUR_VLU1 0xA026
|
||||
+#define AC200_ALARM0_ENABLE 0xA028
|
||||
+#define AC200_ALARM0_IRQ_EN 0xA02C
|
||||
+#define AC200_ALARM0_IRQ_STA 0xA030
|
||||
+#define AC200_ALARM1_WK_HH_MM_SS0 0xA040
|
||||
+#define AC200_ALARM1_WK_HH_MM_SS1 0xA042
|
||||
+#define AC200_ALARM1_ENABLE 0xA044
|
||||
+#define AC200_ALARM1_IRQ_EN 0xA048
|
||||
+#define AC200_ALARM1_IRQ_STA 0xA04C
|
||||
+#define AC200_ALARM_CONFIG 0xA050
|
||||
+#define AC200_LOSC_OUT_GATING 0xA060
|
||||
+#define AC200_GP_DATA(x) (0xA100 + (x) * 2)
|
||||
+#define AC200_RTC_DEB 0xA170
|
||||
+#define AC200_GPL_HOLD_OUTPUT 0xA180
|
||||
+#define AC200_VDD_RTC 0xA190
|
||||
+#define AC200_IC_CHARA0 0xA1F0
|
||||
+#define AC200_IC_CHARA1 0xA1F2
|
||||
+
|
||||
+struct ac200_dev {
|
||||
+ struct regmap *regmap;
|
||||
+ struct regmap_irq_chip_data *regmap_irqc;
|
||||
+};
|
||||
+
|
||||
+#endif /* __LINUX_MFD_AC200_H */
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -0,0 +1,272 @@
|
|||
From 1b528543ea41a9837d39e9ab621631c77122f1aa Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Fri, 16 Aug 2019 16:38:57 +0200
|
||||
Subject: [PATCH 2/4] net: phy: Add support for AC200 EPHY
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
drivers/net/phy/Kconfig | 7 ++
|
||||
drivers/net/phy/Makefile | 1 +
|
||||
drivers/net/phy/ac200.c | 220 +++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 228 insertions(+)
|
||||
create mode 100644 drivers/net/phy/ac200.c
|
||||
|
||||
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
|
||||
index 2e016271e126..248d9384091c 100644
|
||||
--- a/drivers/net/phy/Kconfig
|
||||
+++ b/drivers/net/phy/Kconfig
|
||||
@@ -266,6 +266,13 @@ config ADIN_PHY
|
||||
- ADIN1300 - Robust,Industrial, Low Latency 10/100/1000 Gigabit
|
||||
Ethernet PHY
|
||||
|
||||
+config AC200_PHY
|
||||
+ tristate "AC200 EPHY"
|
||||
+ depends on NVMEM
|
||||
+ depends on OF
|
||||
+ help
|
||||
+ Fast ethernet PHY as found in X-Powers AC200 multi-function device.
|
||||
+
|
||||
config AMD_PHY
|
||||
tristate "AMD PHYs"
|
||||
---help---
|
||||
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
|
||||
index fe5badf13b65..2143587f010e 100644
|
||||
--- a/drivers/net/phy/Makefile
|
||||
+++ b/drivers/net/phy/Makefile
|
||||
@@ -49,6 +49,7 @@ obj-$(CONFIG_SFP) += sfp.o
|
||||
sfp-obj-$(CONFIG_SFP) += sfp-bus.o
|
||||
obj-y += $(sfp-obj-y) $(sfp-obj-m)
|
||||
|
||||
+obj-$(CONFIG_AC200_PHY) += ac200.o
|
||||
obj-$(CONFIG_ADIN_PHY) += adin.o
|
||||
obj-$(CONFIG_AMD_PHY) += amd.o
|
||||
aquantia-objs += aquantia_main.o
|
||||
diff --git a/drivers/net/phy/ac200.c b/drivers/net/phy/ac200.c
|
||||
new file mode 100644
|
||||
index 000000000000..cb713188f7ec
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/phy/ac200.c
|
||||
@@ -0,0 +1,220 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0+
|
||||
+/**
|
||||
+ * Driver for AC200 Ethernet PHY
|
||||
+ *
|
||||
+ * Copyright (c) 2020 Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
+ */
|
||||
+
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/mfd/ac200.h>
|
||||
+#include <linux/nvmem-consumer.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/phy.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+
|
||||
+#define AC200_EPHY_ID 0x00441400
|
||||
+#define AC200_EPHY_ID_MASK 0x0ffffff0
|
||||
+
|
||||
+/* macros for system ephy control 0 register */
|
||||
+#define AC200_EPHY_RESET_INVALID BIT(0)
|
||||
+#define AC200_EPHY_SYSCLK_GATING BIT(1)
|
||||
+
|
||||
+/* macros for system ephy control 1 register */
|
||||
+#define AC200_EPHY_E_EPHY_MII_IO_EN BIT(0)
|
||||
+#define AC200_EPHY_E_LNK_LED_IO_EN BIT(1)
|
||||
+#define AC200_EPHY_E_SPD_LED_IO_EN BIT(2)
|
||||
+#define AC200_EPHY_E_DPX_LED_IO_EN BIT(3)
|
||||
+
|
||||
+/* macros for ephy control register */
|
||||
+#define AC200_EPHY_SHUTDOWN BIT(0)
|
||||
+#define AC200_EPHY_LED_POL BIT(1)
|
||||
+#define AC200_EPHY_CLK_SEL BIT(2)
|
||||
+#define AC200_EPHY_ADDR(x) (((x) & 0x1F) << 4)
|
||||
+#define AC200_EPHY_XMII_SEL BIT(11)
|
||||
+#define AC200_EPHY_CALIB(x) (((x) & 0xF) << 12)
|
||||
+
|
||||
+struct ac200_ephy_dev {
|
||||
+ struct clk *clk;
|
||||
+ struct phy_driver *ephy;
|
||||
+ struct regmap *regmap;
|
||||
+};
|
||||
+
|
||||
+static char *ac200_phy_name = "AC200 EPHY";
|
||||
+
|
||||
+static int ac200_ephy_config_init(struct phy_device *phydev)
|
||||
+{
|
||||
+ const struct ac200_ephy_dev *priv = phydev->drv->driver_data;
|
||||
+ unsigned int value;
|
||||
+ int ret;
|
||||
+
|
||||
+ phy_write(phydev, 0x1f, 0x0100); /* Switch to Page 1 */
|
||||
+ phy_write(phydev, 0x12, 0x4824); /* Disable APS */
|
||||
+
|
||||
+ phy_write(phydev, 0x1f, 0x0200); /* Switch to Page 2 */
|
||||
+ phy_write(phydev, 0x18, 0x0000); /* PHYAFE TRX optimization */
|
||||
+
|
||||
+ phy_write(phydev, 0x1f, 0x0600); /* Switch to Page 6 */
|
||||
+ phy_write(phydev, 0x14, 0x708f); /* PHYAFE TX optimization */
|
||||
+ phy_write(phydev, 0x13, 0xF000); /* PHYAFE RX optimization */
|
||||
+ phy_write(phydev, 0x15, 0x1530);
|
||||
+
|
||||
+ phy_write(phydev, 0x1f, 0x0800); /* Switch to Page 6 */
|
||||
+ phy_write(phydev, 0x18, 0x00bc); /* PHYAFE TRX optimization */
|
||||
+
|
||||
+ phy_write(phydev, 0x1f, 0x0100); /* switch to page 1 */
|
||||
+ phy_clear_bits(phydev, 0x17, BIT(3)); /* disable intelligent IEEE */
|
||||
+
|
||||
+ /* next two blocks disable 802.3az IEEE */
|
||||
+ phy_write(phydev, 0x1f, 0x0200); /* switch to page 2 */
|
||||
+ phy_write(phydev, 0x18, 0x0000);
|
||||
+
|
||||
+ phy_write(phydev, 0x1f, 0x0000); /* switch to page 0 */
|
||||
+ phy_clear_bits_mmd(phydev, 0x7, 0x3c, BIT(1));
|
||||
+
|
||||
+ if (phydev->interface == PHY_INTERFACE_MODE_RMII)
|
||||
+ value = AC200_EPHY_XMII_SEL;
|
||||
+ else
|
||||
+ value = 0;
|
||||
+
|
||||
+ ret = regmap_update_bits(priv->regmap, AC200_EPHY_CTL,
|
||||
+ AC200_EPHY_XMII_SEL, value);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* FIXME: This is H6 specific */
|
||||
+ phy_set_bits(phydev, 0x13, BIT(12));
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int ac200_ephy_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct ac200_dev *ac200 = dev_get_drvdata(pdev->dev.parent);
|
||||
+ struct device *dev = &pdev->dev;
|
||||
+ struct ac200_ephy_dev *priv;
|
||||
+ struct nvmem_cell *calcell;
|
||||
+ struct phy_driver *ephy;
|
||||
+ u16 *caldata, calib;
|
||||
+ size_t callen;
|
||||
+ int ret;
|
||||
+
|
||||
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
+ if (!priv)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ ephy = devm_kzalloc(dev, sizeof(*ephy), GFP_KERNEL);
|
||||
+ if (!ephy)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ priv->clk = devm_clk_get(dev, NULL);
|
||||
+ if (IS_ERR(priv->clk)) {
|
||||
+ dev_err(dev, "Can't obtain the clock!\n");
|
||||
+ return PTR_ERR(priv->clk);
|
||||
+ }
|
||||
+
|
||||
+ calcell = devm_nvmem_cell_get(dev, "calibration");
|
||||
+ if (IS_ERR(calcell)) {
|
||||
+ dev_err(dev, "Unable to find calibration data!\n");
|
||||
+ return PTR_ERR(calcell);
|
||||
+ }
|
||||
+
|
||||
+ caldata = nvmem_cell_read(calcell, &callen);
|
||||
+ if (IS_ERR(caldata)) {
|
||||
+ dev_err(dev, "Unable to read calibration data!\n");
|
||||
+ return PTR_ERR(caldata);
|
||||
+ }
|
||||
+
|
||||
+ if (callen != 2) {
|
||||
+ dev_err(dev, "Calibration data has wrong length: 2 != %zu\n",
|
||||
+ callen);
|
||||
+ kfree(caldata);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ calib = *caldata + 3;
|
||||
+ kfree(caldata);
|
||||
+
|
||||
+ ret = clk_prepare_enable(priv->clk);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ephy->phy_id = AC200_EPHY_ID;
|
||||
+ ephy->phy_id_mask = AC200_EPHY_ID_MASK;
|
||||
+ ephy->name = ac200_phy_name;
|
||||
+ ephy->driver_data = priv;
|
||||
+ ephy->soft_reset = genphy_soft_reset;
|
||||
+ ephy->config_init = ac200_ephy_config_init;
|
||||
+ ephy->suspend = genphy_suspend;
|
||||
+ ephy->resume = genphy_resume;
|
||||
+
|
||||
+ priv->ephy = ephy;
|
||||
+ priv->regmap = ac200->regmap;
|
||||
+ platform_set_drvdata(pdev, priv);
|
||||
+
|
||||
+ ret = regmap_write(ac200->regmap, AC200_SYS_EPHY_CTL0,
|
||||
+ AC200_EPHY_RESET_INVALID |
|
||||
+ AC200_EPHY_SYSCLK_GATING);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = regmap_write(ac200->regmap, AC200_SYS_EPHY_CTL1,
|
||||
+ AC200_EPHY_E_EPHY_MII_IO_EN |
|
||||
+ AC200_EPHY_E_LNK_LED_IO_EN |
|
||||
+ AC200_EPHY_E_SPD_LED_IO_EN |
|
||||
+ AC200_EPHY_E_DPX_LED_IO_EN);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = regmap_write(ac200->regmap, AC200_EPHY_CTL,
|
||||
+ AC200_EPHY_LED_POL |
|
||||
+ AC200_EPHY_CLK_SEL |
|
||||
+ AC200_EPHY_ADDR(1) |
|
||||
+ AC200_EPHY_CALIB(calib));
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = phy_driver_register(priv->ephy, THIS_MODULE);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "Unable to register phy\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int ac200_ephy_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct ac200_ephy_dev *priv = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ phy_driver_unregister(priv->ephy);
|
||||
+
|
||||
+ regmap_write(priv->regmap, AC200_EPHY_CTL, AC200_EPHY_SHUTDOWN);
|
||||
+ regmap_write(priv->regmap, AC200_SYS_EPHY_CTL1, 0);
|
||||
+ regmap_write(priv->regmap, AC200_SYS_EPHY_CTL0, 0);
|
||||
+
|
||||
+ clk_disable_unprepare(priv->clk);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id ac200_ephy_match[] = {
|
||||
+ { .compatible = "x-powers,ac200-ephy" },
|
||||
+ { /* sentinel */ }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, ac200_ephy_match);
|
||||
+
|
||||
+static struct platform_driver ac200_ephy_driver = {
|
||||
+ .probe = ac200_ephy_probe,
|
||||
+ .remove = ac200_ephy_remove,
|
||||
+ .driver = {
|
||||
+ .name = "ac200-ephy",
|
||||
+ .of_match_table = ac200_ephy_match,
|
||||
+ },
|
||||
+};
|
||||
+module_platform_driver(ac200_ephy_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("Jernej Skrabec <jernej.skrabec@siol.net>");
|
||||
+MODULE_DESCRIPTION("AC200 Ethernet PHY driver");
|
||||
+MODULE_LICENSE("GPL");
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
From 1b08baab634bebd4ef94ca449b81d7550c91abf0 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Sun, 12 Jan 2020 12:09:12 +0100
|
||||
Subject: [PATCH 3/4] arm64: dts: allwinner: h6: Add AC200 EPHY related nodes
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 63 ++++++++++++++++++++
|
||||
1 file changed, 63 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
index 3329283e38ab..81caf1e96407 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
@@ -16,6 +16,16 @@
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
+ ac200_pwm_clk: ac200_clk {
|
||||
+ compatible = "pwm-clock";
|
||||
+ #clock-cells = <0>;
|
||||
+ clock-frequency = <24000000>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&pwm1_pin>;
|
||||
+ pwms = <&pwm 1 42 0>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
@@ -248,6 +258,10 @@
|
||||
ths_calibration: thermal-sensor-calibration@14 {
|
||||
reg = <0x14 0x8>;
|
||||
};
|
||||
+
|
||||
+ ephy_calibration: ephy-calibration@2c {
|
||||
+ reg = <0x2c 0x2>;
|
||||
+ };
|
||||
};
|
||||
|
||||
watchdog: watchdog@30090a0 {
|
||||
@@ -291,6 +305,14 @@
|
||||
function = "emac";
|
||||
drive-strength = <40>;
|
||||
};
|
||||
+
|
||||
+ /omit-if-no-ref/
|
||||
+ ext_rmii_pins: rmii_pins {
|
||||
+ pins = "PA0", "PA1", "PA2", "PA3", "PA4",
|
||||
+ "PA5", "PA6", "PA7", "PA8", "PA9";
|
||||
+ function = "emac";
|
||||
+ drive-strength = <40>;
|
||||
+ };
|
||||
|
||||
hdmi_pins: hdmi-pins {
|
||||
pins = "PH8", "PH9", "PH10";
|
||||
@@ -311,6 +333,11 @@
|
||||
pins = "PD23", "PD24";
|
||||
function = "i2c2";
|
||||
};
|
||||
+
|
||||
+ i2c3_pins: i2c3-pins {
|
||||
+ pins = "PB17", "PB18";
|
||||
+ function = "i2c3";
|
||||
+ };
|
||||
|
||||
mmc0_pins: mmc0-pins {
|
||||
pins = "PF0", "PF1", "PF2", "PF3",
|
||||
@@ -329,6 +356,11 @@
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
+ pwm1_pin: pwm1-pin {
|
||||
+ pins = "PB19";
|
||||
+ function = "pwm1";
|
||||
+ };
|
||||
+
|
||||
mmc2_pins: mmc2-pins {
|
||||
pins = "PC1", "PC4", "PC5", "PC6",
|
||||
"PC7", "PC8", "PC9", "PC10",
|
||||
@@ -504,6 +536,37 @@
|
||||
#size-cells = <0>;
|
||||
};
|
||||
|
||||
+ i2c3: i2c@5002c00 {
|
||||
+ compatible = "allwinner,sun50i-h6-i2c",
|
||||
+ "allwinner,sun6i-a31-i2c";
|
||||
+ reg = <0x05002c00 0x400>;
|
||||
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ clocks = <&ccu CLK_BUS_I2C3>;
|
||||
+ resets = <&ccu RST_BUS_I2C3>;
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&i2c3_pins>;
|
||||
+ status = "disabled";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+
|
||||
+ ac200: mfd@10 {
|
||||
+ compatible = "x-powers,ac200";
|
||||
+ reg = <0x10>;
|
||||
+ interrupt-parent = <&pio>;
|
||||
+ interrupts = <1 20 IRQ_TYPE_LEVEL_LOW>;
|
||||
+ interrupt-controller;
|
||||
+ #interrupt-cells = <1>;
|
||||
+
|
||||
+ ac200_ephy: phy {
|
||||
+ compatible = "x-powers,ac200-ephy";
|
||||
+ clocks = <&ac200_pwm_clk>;
|
||||
+ nvmem-cells = <&ephy_calibration>;
|
||||
+ nvmem-cell-names = "calibration";
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
emac: ethernet@5020000 {
|
||||
compatible = "allwinner,sun50i-h6-emac",
|
||||
"allwinner,sun50i-a64-emac";
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
From 15a2214233c38b98cb76e7214c83fbc26068a909 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Sun, 12 Jan 2020 12:19:51 +0100
|
||||
Subject: [PATCH 4/4] arm64: dts: allwinner: h6: tanix-tx6: Enable ethernet
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
.../dts/allwinner/sun50i-h6-tanix-tx6.dts | 32 +++++++++++++++++++
|
||||
1 file changed, 32 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix-tx6.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix-tx6.dts
|
||||
index 83e6cb0e59ce..41a2e3454be5 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix-tx6.dts
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix-tx6.dts
|
||||
@@ -12,6 +12,7 @@
|
||||
compatible = "oranth,tanix-tx6", "allwinner,sun50i-h6";
|
||||
|
||||
aliases {
|
||||
+ ethernet0 = &emac;
|
||||
serial0 = &uart0;
|
||||
};
|
||||
|
||||
@@ -39,6 +40,14 @@
|
||||
};
|
||||
};
|
||||
|
||||
+&ac200_ephy {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&ac200_pwm_clk {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&de {
|
||||
status = "okay";
|
||||
};
|
||||
@@ -47,6 +56,14 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+&emac {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&ext_rmii_pins>;
|
||||
+ phy-mode = "rmii";
|
||||
+ phy-handle = <&ext_rmii_phy>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&ehci0 {
|
||||
status = "okay";
|
||||
};
|
||||
@@ -69,6 +86,17 @@
|
||||
};
|
||||
};
|
||||
|
||||
+&i2c3 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&mdio {
|
||||
+ ext_rmii_phy: ethernet-phy@1 {
|
||||
+ compatible = "ethernet-phy-ieee802.3-c22";
|
||||
+ reg = <1>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
&mmc0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&mmc0_pins>;
|
||||
@@ -86,6 +114,10 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+&pwm {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&r_ir {
|
||||
linux,rc-map-name = "rc-tanix-tx5max";
|
||||
status = "okay";
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -0,0 +1,751 @@
|
|||
From b5cb1681a065bd03b0eb84ca243bc50ab0fa54c1 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Tue, 17 Sep 2019 17:55:07 +0200
|
||||
Subject: [PATCH] WIP: I2S improvements (to be mainlined)
|
||||
|
||||
Work done by Marcus Cooper (codekipper)
|
||||
---
|
||||
sound/soc/sunxi/sun4i-i2s.c | 454 ++++++++++++++++++++++++++++++++----
|
||||
1 file changed, 412 insertions(+), 42 deletions(-)
|
||||
|
||||
diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
|
||||
index d0a8d5810c0a..9a715a6bdbf9 100644
|
||||
--- a/sound/soc/sunxi/sun4i-i2s.c
|
||||
+++ b/sound/soc/sunxi/sun4i-i2s.c
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
#define SUN4I_I2S_CTRL_REG 0x00
|
||||
#define SUN4I_I2S_CTRL_SDO_EN_MASK GENMASK(11, 8)
|
||||
-#define SUN4I_I2S_CTRL_SDO_EN(sdo) BIT(8 + (sdo))
|
||||
+#define SUN4I_I2S_CTRL_SDO_EN(lines) (((1 << (lines)) - 1) << 8)
|
||||
#define SUN4I_I2S_CTRL_MODE_MASK BIT(5)
|
||||
#define SUN4I_I2S_CTRL_MODE_SLAVE (1 << 5)
|
||||
#define SUN4I_I2S_CTRL_MODE_MASTER (0 << 5)
|
||||
@@ -48,6 +48,9 @@
|
||||
#define SUN4I_I2S_FMT0_FMT_I2S (0 << 0)
|
||||
|
||||
#define SUN4I_I2S_FMT1_REG 0x08
|
||||
+#define SUN4I_I2S_FMT1_REG_SEXT_MASK BIT(8)
|
||||
+#define SUN4I_I2S_FMT1_REG_SEXT(sext) ((sext) << 8)
|
||||
+
|
||||
#define SUN4I_I2S_FIFO_TX_REG 0x0c
|
||||
#define SUN4I_I2S_FIFO_RX_REG 0x10
|
||||
|
||||
@@ -100,22 +100,25 @@
|
||||
#define SUN8I_I2S_CTRL_MODE_PCM (0 << 4)
|
||||
|
||||
#define SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK BIT(19)
|
||||
-#define SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED (1 << 19)
|
||||
-#define SUN8I_I2S_FMT0_LRCLK_POLARITY_NORMAL (0 << 19)
|
||||
+#define SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED (1 << 19)
|
||||
+#define SUN8I_I2S_FMT0_LRCLK_POLARITY_NORMAL (0 << 19)
|
||||
#define SUN8I_I2S_FMT0_LRCK_PERIOD_MASK GENMASK(17, 8)
|
||||
#define SUN8I_I2S_FMT0_LRCK_PERIOD(period) ((period - 1) << 8)
|
||||
#define SUN8I_I2S_FMT0_BCLK_POLARITY_MASK BIT(7)
|
||||
-#define SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED (1 << 7)
|
||||
-#define SUN8I_I2S_FMT0_BCLK_POLARITY_NORMAL (0 << 7)
|
||||
+#define SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED (1 << 7)
|
||||
+#define SUN8I_I2S_FMT0_BCLK_POLARITY_NORMAL (0 << 7)
|
||||
+
|
||||
+#define SUN8I_I2S_FMT1_REG_SEXT_MASK GENMASK(5, 4)
|
||||
+#define SUN8I_I2S_FMT1_REG_SEXT(sext) ((sext) << 4)
|
||||
|
||||
#define SUN8I_I2S_INT_STA_REG 0x0c
|
||||
#define SUN8I_I2S_FIFO_TX_REG 0x20
|
||||
|
||||
#define SUN8I_I2S_CHAN_CFG_REG 0x30
|
||||
#define SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK GENMASK(6, 4)
|
||||
-#define SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(chan) ((chan - 1) << 4)
|
||||
+#define SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(chan) (((chan) - 1) << 4)
|
||||
#define SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK GENMASK(2, 0)
|
||||
-#define SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(chan) (chan - 1)
|
||||
+#define SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(chan) ((chan) - 1)
|
||||
|
||||
#define SUN8I_I2S_TX_CHAN_MAP_REG 0x44
|
||||
#define SUN8I_I2S_TX_CHAN_SEL_REG 0x34
|
||||
@@ -123,10 +126,27 @@
|
||||
#define SUN8I_I2S_TX_CHAN_OFFSET(offset) ((offset) << 12)
|
||||
#define SUN8I_I2S_TX_CHAN_EN_MASK GENMASK(11, 4)
|
||||
#define SUN8I_I2S_TX_CHAN_EN(num_chan) (((1 << num_chan) - 1) << 4)
|
||||
+#define SUN8I_I2S_TX_CHAN_SEL_MASK GENMASK(2, 0)
|
||||
+#define SUN8I_I2S_TX_CHAN_SEL(chan) ((chan) - 1)
|
||||
|
||||
#define SUN8I_I2S_RX_CHAN_SEL_REG 0x54
|
||||
#define SUN8I_I2S_RX_CHAN_MAP_REG 0x58
|
||||
|
||||
+/* Defines required for sun50i-h6 support */
|
||||
+#define SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK GENMASK(21, 20)
|
||||
+#define SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(offset) ((offset) << 20)
|
||||
+#define SUN50I_H6_I2S_TX_CHAN_SEL_MASK GENMASK(19, 16)
|
||||
+#define SUN50I_H6_I2S_TX_CHAN_SEL(chan) (((chan) - 1) << 16)
|
||||
+#define SUN50I_H6_I2S_TX_CHAN_EN_MASK GENMASK(15, 0)
|
||||
+#define SUN50I_H6_I2S_TX_CHAN_EN(num_chan) (((1 << (num_chan)) - 1))
|
||||
+
|
||||
+#define SUN50I_H6_I2S_TX_CHAN_MAP0_REG 0x44
|
||||
+#define SUN50I_H6_I2S_TX_CHAN_MAP1_REG 0x48
|
||||
+
|
||||
+#define SUN50I_H6_I2S_RX_CHAN_SEL_REG 0x64
|
||||
+#define SUN50I_H6_I2S_RX_CHAN_MAP0_REG 0x68
|
||||
+#define SUN50I_H6_I2S_RX_CHAN_MAP1_REG 0x6C
|
||||
+
|
||||
struct sun4i_i2s;
|
||||
|
||||
/**
|
||||
@@ -156,7 +179,16 @@ struct sun4i_i2s_quirks {
|
||||
s8 (*get_wss)(const struct sun4i_i2s *, int);
|
||||
int (*set_chan_cfg)(const struct sun4i_i2s *,
|
||||
const struct snd_pcm_hw_params *);
|
||||
- int (*set_fmt)(const struct sun4i_i2s *, unsigned int);
|
||||
+ int (*set_fmt)(struct sun4i_i2s *, unsigned int);
|
||||
+ void (*set_fmt_sext)(const struct sun4i_i2s *, unsigned int);
|
||||
+ void (*set_txchanoffset)(const struct sun4i_i2s *, int);
|
||||
+ void (*set_rxchanoffset)(const struct sun4i_i2s *);
|
||||
+ void (*set_txchanen)(const struct sun4i_i2s *, int, int);
|
||||
+ void (*set_rxchanen)(const struct sun4i_i2s *, int);
|
||||
+ void (*set_txchansel)(const struct sun4i_i2s *, int, int);
|
||||
+ void (*set_rxchansel)(const struct sun4i_i2s *, int);
|
||||
+ void (*set_txchanmap)(const struct sun4i_i2s *, int, int);
|
||||
+ void (*set_rxchanmap)(const struct sun4i_i2s *, int);
|
||||
};
|
||||
|
||||
struct sun4i_i2s {
|
||||
@@ -169,6 +201,7 @@ struct sun4i_i2s {
|
||||
unsigned int mclk_freq;
|
||||
unsigned int slots;
|
||||
unsigned int slot_width;
|
||||
+ unsigned int offset;
|
||||
|
||||
struct snd_dmaengine_dai_dma_data capture_dma_data;
|
||||
struct snd_dmaengine_dai_dma_data playback_dma_data;
|
||||
@@ -354,6 +387,9 @@ static int sun4i_i2s_set_clk_rate(struct snd_soc_dai *dai,
|
||||
|
||||
regmap_field_write(i2s->field_clkdiv_mclk_en, 1);
|
||||
|
||||
+ /* Set sign extension to pad out LSB with 0 */
|
||||
+ i2s->variant->set_fmt_sext(i2s, 0);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -396,8 +432,8 @@ static int sun4i_i2s_set_chan_cfg(const struct sun4i_i2s *i2s,
|
||||
unsigned int channels = params_channels(params);
|
||||
|
||||
/* Map the channels for playback and capture */
|
||||
- regmap_write(i2s->regmap, SUN4I_I2S_TX_CHAN_MAP_REG, 0x76543210);
|
||||
- regmap_write(i2s->regmap, SUN4I_I2S_RX_CHAN_MAP_REG, 0x00003210);
|
||||
+ i2s->variant->set_txchanmap(i2s, 0, 0x76543210);
|
||||
+ i2s->variant->set_rxchanmap(i2s, 0x3210);
|
||||
|
||||
/* Configure the channels */
|
||||
regmap_update_bits(i2s->regmap, SUN4I_I2S_TX_CHAN_SEL_REG,
|
||||
@@ -421,16 +457,12 @@ static int sun8i_i2s_set_chan_cfg(const struct sun4i_i2s *i2s,
|
||||
slots = i2s->slots;
|
||||
|
||||
/* Map the channels for playback and capture */
|
||||
- regmap_write(i2s->regmap, SUN8I_I2S_TX_CHAN_MAP_REG, 0x76543210);
|
||||
- regmap_write(i2s->regmap, SUN8I_I2S_RX_CHAN_MAP_REG, 0x76543210);
|
||||
+ i2s->variant->set_txchanmap(i2s, 0, 0x76543210);
|
||||
+ i2s->variant->set_rxchanmap(i2s, 0x3210);
|
||||
|
||||
/* Configure the channels */
|
||||
- regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
|
||||
- SUN4I_I2S_CHAN_SEL_MASK,
|
||||
- SUN4I_I2S_CHAN_SEL(channels));
|
||||
- regmap_update_bits(i2s->regmap, SUN8I_I2S_RX_CHAN_SEL_REG,
|
||||
- SUN4I_I2S_CHAN_SEL_MASK,
|
||||
- SUN4I_I2S_CHAN_SEL(channels));
|
||||
+ i2s->variant->set_txchansel(i2s, 0, channels);
|
||||
+ i2s->variant->set_rxchansel(i2s, channels);
|
||||
|
||||
regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG,
|
||||
SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK,
|
||||
@@ -448,7 +480,10 @@ static int sun8i_i2s_set_chan_cfg(const struct sun4i_i2s *i2s,
|
||||
break;
|
||||
|
||||
case SND_SOC_DAIFMT_I2S:
|
||||
- lrck_period = params_physical_width(params);
|
||||
+ if (i2s->slot_width)
|
||||
+ lrck_period = i2s->slot_width;
|
||||
+ else
|
||||
+ lrck_period = params_physical_width(params);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -466,6 +501,166 @@ static int sun8i_i2s_set_chan_cfg(const struct sun4i_i2s *i2s,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void sun8i_i2s_set_txchanoffset(const struct sun4i_i2s *i2s, int output)
|
||||
+{
|
||||
+ if (output >= 0 && output < 4)
|
||||
+ regmap_update_bits(i2s->regmap,
|
||||
+ SUN8I_I2S_TX_CHAN_SEL_REG + (output * 4),
|
||||
+ SUN8I_I2S_TX_CHAN_OFFSET_MASK,
|
||||
+ SUN8I_I2S_TX_CHAN_OFFSET(i2s->offset));
|
||||
+}
|
||||
+
|
||||
+static void sun8i_i2s_set_rxchanoffset(const struct sun4i_i2s *i2s)
|
||||
+{
|
||||
+ regmap_update_bits(i2s->regmap,
|
||||
+ SUN8I_I2S_RX_CHAN_SEL_REG,
|
||||
+ SUN8I_I2S_TX_CHAN_OFFSET_MASK,
|
||||
+ SUN8I_I2S_TX_CHAN_OFFSET(i2s->offset));
|
||||
+}
|
||||
+
|
||||
+static void sun50i_h6_i2s_set_txchanoffset(const struct sun4i_i2s *i2s, int output)
|
||||
+{
|
||||
+ if (output >= 0 && output < 4)
|
||||
+ regmap_update_bits(i2s->regmap,
|
||||
+ SUN8I_I2S_TX_CHAN_SEL_REG + (output * 4),
|
||||
+ SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK,
|
||||
+ SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(i2s->offset));
|
||||
+}
|
||||
+
|
||||
+static void sun50i_h6_i2s_set_rxchanoffset(const struct sun4i_i2s *i2s)
|
||||
+{
|
||||
+ regmap_update_bits(i2s->regmap,
|
||||
+ SUN50I_H6_I2S_RX_CHAN_SEL_REG,
|
||||
+ SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK,
|
||||
+ SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(i2s->offset));
|
||||
+}
|
||||
+
|
||||
+static void sun8i_i2s_set_txchanen(const struct sun4i_i2s *i2s, int output,
|
||||
+ int channel)
|
||||
+{
|
||||
+ if (output >= 0 && output < 4)
|
||||
+ regmap_update_bits(i2s->regmap,
|
||||
+ SUN8I_I2S_TX_CHAN_SEL_REG + (output * 4),
|
||||
+ SUN8I_I2S_TX_CHAN_EN_MASK,
|
||||
+ SUN8I_I2S_TX_CHAN_EN(channel));
|
||||
+}
|
||||
+
|
||||
+static void sun8i_i2s_set_rxchanen(const struct sun4i_i2s *i2s, int channel)
|
||||
+{
|
||||
+ regmap_update_bits(i2s->regmap,
|
||||
+ SUN8I_I2S_RX_CHAN_SEL_REG,
|
||||
+ SUN8I_I2S_TX_CHAN_EN_MASK,
|
||||
+ SUN8I_I2S_TX_CHAN_EN(channel));
|
||||
+}
|
||||
+
|
||||
+static void sun50i_h6_i2s_set_txchanen(const struct sun4i_i2s *i2s, int output,
|
||||
+ int channel)
|
||||
+{
|
||||
+ if (output >= 0 && output < 4)
|
||||
+ regmap_update_bits(i2s->regmap,
|
||||
+ SUN8I_I2S_TX_CHAN_SEL_REG + (output * 4),
|
||||
+ SUN50I_H6_I2S_TX_CHAN_EN_MASK,
|
||||
+ SUN50I_H6_I2S_TX_CHAN_EN(channel));
|
||||
+}
|
||||
+
|
||||
+static void sun50i_h6_i2s_set_rxchanen(const struct sun4i_i2s *i2s, int channel)
|
||||
+{
|
||||
+ regmap_update_bits(i2s->regmap,
|
||||
+ SUN50I_H6_I2S_RX_CHAN_SEL_REG,
|
||||
+ SUN50I_H6_I2S_TX_CHAN_EN_MASK,
|
||||
+ SUN50I_H6_I2S_TX_CHAN_EN(channel));
|
||||
+}
|
||||
+
|
||||
+static void sun4i_i2s_set_txchansel(const struct sun4i_i2s *i2s, int output,
|
||||
+ int channel)
|
||||
+{
|
||||
+ /* Configure the channels */
|
||||
+ regmap_write(i2s->regmap,
|
||||
+ SUN4I_I2S_TX_CHAN_SEL_REG,
|
||||
+ SUN4I_I2S_CHAN_SEL(channel));
|
||||
+}
|
||||
+
|
||||
+static void sun8i_i2s_set_txchansel(const struct sun4i_i2s *i2s, int output,
|
||||
+ int channel)
|
||||
+{
|
||||
+ if (output >= 0 && output < 4)
|
||||
+ regmap_update_bits(i2s->regmap,
|
||||
+ SUN8I_I2S_TX_CHAN_SEL_REG + (output * 4),
|
||||
+ SUN8I_I2S_TX_CHAN_SEL_MASK,
|
||||
+ SUN8I_I2S_TX_CHAN_SEL(channel));
|
||||
+}
|
||||
+
|
||||
+static void sun4i_i2s_set_rxchansel(const struct sun4i_i2s *i2s, int channel)
|
||||
+{
|
||||
+ /* Configure the channels */
|
||||
+ regmap_write(i2s->regmap,
|
||||
+ SUN4I_I2S_RX_CHAN_SEL_REG,
|
||||
+ SUN4I_I2S_CHAN_SEL(channel));
|
||||
+}
|
||||
+
|
||||
+static void sun8i_i2s_set_rxchansel(const struct sun4i_i2s *i2s, int channel)
|
||||
+{
|
||||
+ regmap_update_bits(i2s->regmap,
|
||||
+ SUN8I_I2S_RX_CHAN_SEL_REG,
|
||||
+ SUN8I_I2S_TX_CHAN_SEL_MASK,
|
||||
+ SUN8I_I2S_TX_CHAN_SEL(channel));
|
||||
+}
|
||||
+
|
||||
+static void sun50i_h6_i2s_set_txchansel(const struct sun4i_i2s *i2s, int output,
|
||||
+ int channel)
|
||||
+{
|
||||
+ if (output >= 0 && output < 4)
|
||||
+ regmap_update_bits(i2s->regmap,
|
||||
+ SUN8I_I2S_TX_CHAN_SEL_REG + (output * 4),
|
||||
+ SUN50I_H6_I2S_TX_CHAN_SEL_MASK,
|
||||
+ SUN50I_H6_I2S_TX_CHAN_SEL(channel));
|
||||
+}
|
||||
+
|
||||
+static void sun50i_h6_i2s_set_rxchansel(const struct sun4i_i2s *i2s, int channel)
|
||||
+{
|
||||
+ regmap_update_bits(i2s->regmap,
|
||||
+ SUN50I_H6_I2S_RX_CHAN_SEL_REG,
|
||||
+ SUN50I_H6_I2S_TX_CHAN_SEL_MASK,
|
||||
+ SUN50I_H6_I2S_TX_CHAN_SEL(channel));
|
||||
+}
|
||||
+
|
||||
+static void sun4i_i2s_set_txchanmap(const struct sun4i_i2s *i2s, int output,
|
||||
+ int channel)
|
||||
+{
|
||||
+ regmap_write(i2s->regmap, SUN4I_I2S_TX_CHAN_MAP_REG, channel);
|
||||
+}
|
||||
+
|
||||
+static void sun8i_i2s_set_txchanmap(const struct sun4i_i2s *i2s, int output,
|
||||
+ int channel)
|
||||
+{
|
||||
+ if (output >= 0 && output < 4)
|
||||
+ regmap_write(i2s->regmap,
|
||||
+ SUN8I_I2S_TX_CHAN_MAP_REG + (output * 4), channel);
|
||||
+}
|
||||
+
|
||||
+static void sun4i_i2s_set_rxchanmap(const struct sun4i_i2s *i2s, int channel)
|
||||
+{
|
||||
+ regmap_write(i2s->regmap, SUN4I_I2S_RX_CHAN_MAP_REG, channel);
|
||||
+}
|
||||
+
|
||||
+static void sun8i_i2s_set_rxchanmap(const struct sun4i_i2s *i2s, int channel)
|
||||
+{
|
||||
+ regmap_write(i2s->regmap, SUN8I_I2S_RX_CHAN_MAP_REG, channel);
|
||||
+}
|
||||
+
|
||||
+static void sun50i_h6_i2s_set_txchanmap(const struct sun4i_i2s *i2s, int output,
|
||||
+ int channel)
|
||||
+{
|
||||
+ if (output >= 0 && output < 4)
|
||||
+ regmap_write(i2s->regmap,
|
||||
+ SUN50I_H6_I2S_TX_CHAN_MAP1_REG + (output * 8), channel);
|
||||
+}
|
||||
+
|
||||
+static void sun50i_h6_i2s_set_rxchanmap(const struct sun4i_i2s *i2s, int channel)
|
||||
+{
|
||||
+ regmap_write(i2s->regmap, SUN50I_H6_I2S_RX_CHAN_MAP1_REG, channel);
|
||||
+}
|
||||
+
|
||||
static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params,
|
||||
struct snd_soc_dai *dai)
|
||||
@@ -477,6 +672,7 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
|
||||
unsigned int slots = channels;
|
||||
int ret, sr, wss;
|
||||
u32 width;
|
||||
+ int lines;
|
||||
|
||||
if (i2s->slots)
|
||||
slots = i2s->slots;
|
||||
@@ -490,10 +686,82 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
|
||||
return ret;
|
||||
}
|
||||
|
||||
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
+ if (channels > dai->driver->playback.channels_max ||
|
||||
+ channels < dai->driver->playback.channels_min) {
|
||||
+ dev_err(dai->dev, "Unsupported number of channels: %d\n",
|
||||
+ channels);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ lines = (channels + 1) / 2;
|
||||
+
|
||||
+ /* Enable the required output lines */
|
||||
+ regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
|
||||
+ SUN4I_I2S_CTRL_SDO_EN_MASK,
|
||||
+ SUN4I_I2S_CTRL_SDO_EN(lines));
|
||||
+
|
||||
+ i2s->variant->set_txchanmap(i2s, 0, 0x10);
|
||||
+ i2s->variant->set_txchansel(i2s, 0, channels > 1 ? 2 : 1);
|
||||
+
|
||||
+ if (i2s->variant->set_txchanen)
|
||||
+ i2s->variant->set_txchanen(i2s, 0, 2);
|
||||
+
|
||||
+ if (i2s->variant->set_txchanoffset) {
|
||||
+ regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG,
|
||||
+ SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK,
|
||||
+ SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(channels));
|
||||
+
|
||||
+ if (channels > 2) {
|
||||
+ i2s->variant->set_txchanmap(i2s, 1, 0x32);
|
||||
+ i2s->variant->set_txchanoffset(i2s, 1);
|
||||
+ i2s->variant->set_txchansel(i2s, 1,
|
||||
+ channels > 3 ? 2 : 1);
|
||||
+ i2s->variant->set_txchanen(i2s, 1, 2);
|
||||
+ }
|
||||
+ if (channels > 4) {
|
||||
+ i2s->variant->set_txchanmap(i2s, 2, 0x54);
|
||||
+ i2s->variant->set_txchanoffset(i2s, 2);
|
||||
+ i2s->variant->set_txchansel(i2s, 2,
|
||||
+ channels > 5 ? 2 : 1);
|
||||
+ i2s->variant->set_txchanen(i2s, 2, 2);
|
||||
+ }
|
||||
+ if (channels > 6) {
|
||||
+ i2s->variant->set_txchanmap(i2s, 3, 0x76);
|
||||
+ i2s->variant->set_txchanoffset(i2s, 3);
|
||||
+ i2s->variant->set_txchansel(i2s, 3,
|
||||
+ channels > 6 ? 2 : 1);
|
||||
+ i2s->variant->set_txchanen(i2s, 3, 2);
|
||||
+ }
|
||||
+ }
|
||||
+ } else {
|
||||
+ if (channels > dai->driver->capture.channels_max ||
|
||||
+ channels < dai->driver->capture.channels_min) {
|
||||
+ dev_err(dai->dev, "Unsupported number of channels: %d\n",
|
||||
+ channels);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ /* Map the channels for capture */
|
||||
+ i2s->variant->set_rxchanmap(i2s, 0x10);
|
||||
+ i2s->variant->set_rxchansel(i2s, channels);
|
||||
+
|
||||
+ if (i2s->variant->set_rxchanen)
|
||||
+ i2s->variant->set_rxchanen(i2s, channels);
|
||||
+
|
||||
+ if (i2s->variant->set_rxchanoffset)
|
||||
+ regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG,
|
||||
+ SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK,
|
||||
+ SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(channels));
|
||||
+ }
|
||||
+
|
||||
switch (params_physical_width(params)) {
|
||||
case 16:
|
||||
width = DMA_SLAVE_BUSWIDTH_2_BYTES;
|
||||
break;
|
||||
+ case 32:
|
||||
+ width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
+ break;
|
||||
default:
|
||||
dev_err(dai->dev, "Unsupported physical sample width: %d\n",
|
||||
params_physical_width(params));
|
||||
@@ -516,7 +784,7 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
|
||||
slots, slot_width);
|
||||
}
|
||||
|
||||
-static int sun4i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
|
||||
+static int sun4i_i2s_set_soc_fmt(struct sun4i_i2s *i2s,
|
||||
unsigned int fmt)
|
||||
{
|
||||
u32 val;
|
||||
@@ -589,11 +857,10 @@ static int sun4i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int sun8i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
|
||||
+static int sun8i_i2s_set_soc_fmt(struct sun4i_i2s *i2s,
|
||||
unsigned int fmt)
|
||||
{
|
||||
u32 mode, val;
|
||||
- u8 offset;
|
||||
|
||||
/*
|
||||
* DAI clock polarity
|
||||
@@ -632,27 +899,27 @@ static int sun8i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
|
||||
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
|
||||
case SND_SOC_DAIFMT_DSP_A:
|
||||
mode = SUN8I_I2S_CTRL_MODE_PCM;
|
||||
- offset = 1;
|
||||
+ i2s->offset = 1;
|
||||
break;
|
||||
|
||||
case SND_SOC_DAIFMT_DSP_B:
|
||||
mode = SUN8I_I2S_CTRL_MODE_PCM;
|
||||
- offset = 0;
|
||||
+ i2s->offset = 0;
|
||||
break;
|
||||
|
||||
case SND_SOC_DAIFMT_I2S:
|
||||
mode = SUN8I_I2S_CTRL_MODE_LEFT;
|
||||
- offset = 1;
|
||||
+ i2s->offset = 1;
|
||||
break;
|
||||
|
||||
case SND_SOC_DAIFMT_LEFT_J:
|
||||
mode = SUN8I_I2S_CTRL_MODE_LEFT;
|
||||
- offset = 0;
|
||||
+ i2s->offset = 0;
|
||||
break;
|
||||
|
||||
case SND_SOC_DAIFMT_RIGHT_J:
|
||||
mode = SUN8I_I2S_CTRL_MODE_RIGHT;
|
||||
- offset = 0;
|
||||
+ i2s->offset = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -913,12 +933,8 @@ static int sun8i_i2s_set_soc_fmt(struct sun4i_i2s *i2s,
|
||||
|
||||
regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
|
||||
SUN8I_I2S_CTRL_MODE_MASK, mode);
|
||||
- regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
|
||||
- SUN8I_I2S_TX_CHAN_OFFSET_MASK,
|
||||
- SUN8I_I2S_TX_CHAN_OFFSET(offset));
|
||||
- regmap_update_bits(i2s->regmap, SUN8I_I2S_RX_CHAN_SEL_REG,
|
||||
- SUN8I_I2S_TX_CHAN_OFFSET_MASK,
|
||||
- SUN8I_I2S_TX_CHAN_OFFSET(offset));
|
||||
+ i2s->variant->set_txchanoffset(i2s, 0);
|
||||
+ i2s->variant->set_rxchanoffset(i2s);
|
||||
|
||||
/* DAI clock master masks */
|
||||
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
|
||||
@@ -691,6 +954,22 @@ static int sun8i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void sun4i_i2s_set_fmt_sext(const struct sun4i_i2s *i2s,
|
||||
+ unsigned int sext)
|
||||
+{
|
||||
+ regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT1_REG,
|
||||
+ SUN4I_I2S_FMT1_REG_SEXT_MASK,
|
||||
+ SUN4I_I2S_FMT1_REG_SEXT(sext));
|
||||
+}
|
||||
+
|
||||
+static void sun8i_i2s_set_fmt_sext(const struct sun4i_i2s *i2s,
|
||||
+ unsigned int sext)
|
||||
+{
|
||||
+ regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT1_REG,
|
||||
+ SUN8I_I2S_FMT1_REG_SEXT_MASK,
|
||||
+ SUN8I_I2S_FMT1_REG_SEXT(sext));
|
||||
+}
|
||||
+
|
||||
static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
|
||||
{
|
||||
struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
|
||||
@@ -717,9 +996,9 @@ static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
|
||||
static void sun4i_i2s_start_capture(struct sun4i_i2s *i2s)
|
||||
{
|
||||
/* Flush RX FIFO */
|
||||
- regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
|
||||
- SUN4I_I2S_FIFO_CTRL_FLUSH_RX,
|
||||
- SUN4I_I2S_FIFO_CTRL_FLUSH_RX);
|
||||
+ regmap_write_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
|
||||
+ SUN4I_I2S_FIFO_CTRL_FLUSH_RX,
|
||||
+ SUN4I_I2S_FIFO_CTRL_FLUSH_RX);
|
||||
|
||||
/* Clear RX counter */
|
||||
regmap_write(i2s->regmap, SUN4I_I2S_RX_CNT_REG, 0);
|
||||
@@ -738,9 +1017,9 @@ static void sun4i_i2s_start_capture(struct sun4i_i2s *i2s)
|
||||
static void sun4i_i2s_start_playback(struct sun4i_i2s *i2s)
|
||||
{
|
||||
/* Flush TX FIFO */
|
||||
- regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
|
||||
- SUN4I_I2S_FIFO_CTRL_FLUSH_TX,
|
||||
- SUN4I_I2S_FIFO_CTRL_FLUSH_TX);
|
||||
+ regmap_write_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
|
||||
+ SUN4I_I2S_FIFO_CTRL_FLUSH_TX,
|
||||
+ SUN4I_I2S_FIFO_CTRL_FLUSH_TX);
|
||||
|
||||
/* Clear TX counter */
|
||||
regmap_write(i2s->regmap, SUN4I_I2S_TX_CNT_REG, 0);
|
||||
@@ -862,6 +1141,10 @@ static int sun4i_i2s_dai_probe(struct snd_soc_dai *dai)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+#define SUN4I_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
|
||||
+ SNDRV_PCM_FMTBIT_S20_LE | \
|
||||
+ SNDRV_PCM_FMTBIT_S24_LE)
|
||||
+
|
||||
static struct snd_soc_dai_driver sun4i_i2s_dai = {
|
||||
.probe = sun4i_i2s_dai_probe,
|
||||
.capture = {
|
||||
@@ -869,14 +1152,14 @@ static struct snd_soc_dai_driver sun4i_i2s_dai = {
|
||||
.channels_min = 1,
|
||||
.channels_max = 8,
|
||||
.rates = SNDRV_PCM_RATE_8000_192000,
|
||||
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
|
||||
+ .formats = SUN4I_FORMATS,
|
||||
},
|
||||
.playback = {
|
||||
.stream_name = "Playback",
|
||||
.channels_min = 1,
|
||||
.channels_max = 8,
|
||||
.rates = SNDRV_PCM_RATE_8000_192000,
|
||||
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
|
||||
+ .formats = SUN4I_FORMATS,
|
||||
},
|
||||
.ops = &sun4i_i2s_dai_ops,
|
||||
.symmetric_rates = 1,
|
||||
@@ -971,6 +1254,22 @@ static const struct reg_default sun8i_i2s_reg_defaults[] = {
|
||||
{ SUN8I_I2S_RX_CHAN_MAP_REG, 0x00000000 },
|
||||
};
|
||||
|
||||
+static const struct reg_default sun50i_i2s_reg_defaults[] = {
|
||||
+ { SUN4I_I2S_CTRL_REG, 0x00060000 },
|
||||
+ { SUN4I_I2S_FMT0_REG, 0x00000033 },
|
||||
+ { SUN4I_I2S_FMT1_REG, 0x00000030 },
|
||||
+ { SUN4I_I2S_FIFO_CTRL_REG, 0x000400f0 },
|
||||
+ { SUN4I_I2S_DMA_INT_CTRL_REG, 0x00000000 },
|
||||
+ { SUN4I_I2S_CLK_DIV_REG, 0x00000000 },
|
||||
+ { SUN8I_I2S_CHAN_CFG_REG, 0x00000000 },
|
||||
+ { SUN8I_I2S_TX_CHAN_SEL_REG, 0x00000000 },
|
||||
+ { SUN50I_H6_I2S_TX_CHAN_MAP0_REG, 0x00000000 },
|
||||
+ { SUN50I_H6_I2S_TX_CHAN_MAP1_REG, 0x00000000 },
|
||||
+ { SUN50I_H6_I2S_RX_CHAN_SEL_REG, 0x00000000 },
|
||||
+ { SUN50I_H6_I2S_RX_CHAN_MAP0_REG, 0x00000000 },
|
||||
+ { SUN50I_H6_I2S_RX_CHAN_MAP1_REG, 0x00000000 },
|
||||
+};
|
||||
+
|
||||
static const struct regmap_config sun4i_i2s_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
@@ -998,6 +1297,19 @@ static const struct regmap_config sun8i_i2s_regmap_config = {
|
||||
.volatile_reg = sun8i_i2s_volatile_reg,
|
||||
};
|
||||
|
||||
+static const struct regmap_config sun50i_i2s_regmap_config = {
|
||||
+ .reg_bits = 32,
|
||||
+ .reg_stride = 4,
|
||||
+ .val_bits = 32,
|
||||
+ .max_register = SUN50I_H6_I2S_RX_CHAN_MAP1_REG,
|
||||
+ .cache_type = REGCACHE_FLAT,
|
||||
+ .reg_defaults = sun50i_i2s_reg_defaults,
|
||||
+ .num_reg_defaults = ARRAY_SIZE(sun50i_i2s_reg_defaults),
|
||||
+ .writeable_reg = sun4i_i2s_wr_reg,
|
||||
+ .readable_reg = sun8i_i2s_rd_reg,
|
||||
+ .volatile_reg = sun8i_i2s_volatile_reg,
|
||||
+};
|
||||
+
|
||||
static int sun4i_i2s_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct sun4i_i2s *i2s = dev_get_drvdata(dev);
|
||||
@@ -1077,6 +1389,11 @@ static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = {
|
||||
.get_wss = sun4i_i2s_get_wss,
|
||||
.set_chan_cfg = sun4i_i2s_set_chan_cfg,
|
||||
.set_fmt = sun4i_i2s_set_soc_fmt,
|
||||
+ .set_fmt_sext = sun4i_i2s_set_fmt_sext,
|
||||
+ .set_txchansel = sun4i_i2s_set_txchansel,
|
||||
+ .set_rxchansel = sun4i_i2s_set_rxchansel,
|
||||
+ .set_txchanmap = sun4i_i2s_set_txchanmap,
|
||||
+ .set_rxchanmap = sun4i_i2s_set_rxchanmap,
|
||||
};
|
||||
|
||||
static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = {
|
||||
@@ -1095,6 +1412,11 @@ static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = {
|
||||
.get_wss = sun4i_i2s_get_wss,
|
||||
.set_chan_cfg = sun4i_i2s_set_chan_cfg,
|
||||
.set_fmt = sun4i_i2s_set_soc_fmt,
|
||||
+ .set_fmt_sext = sun4i_i2s_set_fmt_sext,
|
||||
+ .set_txchansel = sun4i_i2s_set_txchansel,
|
||||
+ .set_rxchansel = sun4i_i2s_set_rxchansel,
|
||||
+ .set_txchanmap = sun4i_i2s_set_txchanmap,
|
||||
+ .set_rxchanmap = sun4i_i2s_set_rxchanmap,
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -1118,6 +1440,9 @@ static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = {
|
||||
.get_wss = sun4i_i2s_get_wss,
|
||||
.set_chan_cfg = sun4i_i2s_set_chan_cfg,
|
||||
.set_fmt = sun4i_i2s_set_soc_fmt,
|
||||
+ .set_fmt_sext = sun4i_i2s_set_fmt_sext,
|
||||
+ .set_txchansel = sun4i_i2s_set_txchansel,
|
||||
+ .set_rxchansel = sun4i_i2s_set_rxchansel,
|
||||
};
|
||||
|
||||
static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = {
|
||||
@@ -1136,6 +1461,15 @@ static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = {
|
||||
.get_wss = sun8i_i2s_get_sr_wss,
|
||||
.set_chan_cfg = sun8i_i2s_set_chan_cfg,
|
||||
.set_fmt = sun8i_i2s_set_soc_fmt,
|
||||
+ .set_fmt_sext = sun8i_i2s_set_fmt_sext,
|
||||
+ .set_txchanoffset = sun8i_i2s_set_txchanoffset,
|
||||
+ .set_rxchanoffset = sun8i_i2s_set_rxchanoffset,
|
||||
+ .set_txchanen = sun8i_i2s_set_txchanen,
|
||||
+ .set_rxchanen = sun8i_i2s_set_rxchanen,
|
||||
+ .set_txchansel = sun8i_i2s_set_txchansel,
|
||||
+ .set_rxchansel = sun8i_i2s_set_rxchansel,
|
||||
+ .set_txchanmap = sun8i_i2s_set_txchanmap,
|
||||
+ .set_rxchanmap = sun8i_i2s_set_rxchanmap,
|
||||
};
|
||||
|
||||
static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = {
|
||||
@@ -1154,6 +1488,38 @@ static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = {
|
||||
.get_wss = sun4i_i2s_get_wss,
|
||||
.set_chan_cfg = sun4i_i2s_set_chan_cfg,
|
||||
.set_fmt = sun4i_i2s_set_soc_fmt,
|
||||
+ .set_fmt_sext = sun4i_i2s_set_fmt_sext,
|
||||
+ .set_txchansel = sun4i_i2s_set_txchansel,
|
||||
+ .set_rxchansel = sun4i_i2s_set_rxchansel,
|
||||
+ .set_txchanmap = sun4i_i2s_set_txchanmap,
|
||||
+ .set_rxchanmap = sun4i_i2s_set_rxchanmap,
|
||||
+};
|
||||
+
|
||||
+static const struct sun4i_i2s_quirks sun50i_h6_i2s_quirks = {
|
||||
+ .has_reset = true,
|
||||
+ .reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG,
|
||||
+ .sun4i_i2s_regmap = &sun50i_i2s_regmap_config,
|
||||
+ .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8),
|
||||
+ .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 2),
|
||||
+ .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 6),
|
||||
+ .bclk_dividers = sun8i_i2s_clk_div,
|
||||
+ .num_bclk_dividers = ARRAY_SIZE(sun8i_i2s_clk_div),
|
||||
+ .mclk_dividers = sun8i_i2s_clk_div,
|
||||
+ .num_mclk_dividers = ARRAY_SIZE(sun8i_i2s_clk_div),
|
||||
+ .get_bclk_parent_rate = sun8i_i2s_get_bclk_parent_rate,
|
||||
+ .get_sr = sun8i_i2s_get_sr_wss,
|
||||
+ .get_wss = sun8i_i2s_get_sr_wss,
|
||||
+ .set_chan_cfg = sun8i_i2s_set_chan_cfg,
|
||||
+ .set_fmt = sun8i_i2s_set_soc_fmt,
|
||||
+ .set_fmt_sext = sun8i_i2s_set_fmt_sext,
|
||||
+ .set_txchanoffset = sun50i_h6_i2s_set_txchanoffset,
|
||||
+ .set_rxchanoffset = sun50i_h6_i2s_set_rxchanoffset,
|
||||
+ .set_txchanen = sun50i_h6_i2s_set_txchanen,
|
||||
+ .set_rxchanen = sun50i_h6_i2s_set_rxchanen,
|
||||
+ .set_txchansel = sun50i_h6_i2s_set_txchansel,
|
||||
+ .set_rxchansel = sun50i_h6_i2s_set_rxchansel,
|
||||
+ .set_txchanmap = sun50i_h6_i2s_set_txchanmap,
|
||||
+ .set_rxchanmap = sun50i_h6_i2s_set_rxchanmap,
|
||||
};
|
||||
|
||||
static int sun4i_i2s_init_regmap_fields(struct device *dev,
|
||||
@@ -1325,6 +1691,10 @@ static const struct of_device_id sun4i_i2s_match[] = {
|
||||
.compatible = "allwinner,sun50i-a64-codec-i2s",
|
||||
.data = &sun50i_a64_codec_i2s_quirks,
|
||||
},
|
||||
+ {
|
||||
+ .compatible = "allwinner,sun50i-h6-i2s",
|
||||
+ .data = &sun50i_h6_i2s_quirks,
|
||||
+ },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sun4i_i2s_match);
|
||||
--
|
||||
2.23.0
|
||||
|
||||
From 2da43795f6191505b2dd6e30938c3af4c90bf745 Mon Sep 17 00:00:00 2001
|
||||
From: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
Date: Thu, 7 Nov 2019 07:36:11 +0100
|
||||
Subject: [PATCH] sound: soc: sun4i-i2s: Fix rate calculation
|
||||
|
||||
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
|
||||
---
|
||||
sound/soc/sunxi/sun4i-i2s.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
|
||||
index d0a8d5810c0a..6c4241cb6509 100644
|
||||
--- a/sound/soc/sunxi/sun4i-i2s.c
|
||||
+++ b/sound/soc/sunxi/sun4i-i2s.c
|
||||
@@ -334,6 +334,9 @@ static int sun4i_i2s_set_clk_rate(struct snd_soc_dai *dai,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
+ if (i2s->slot_width)
|
||||
+ slot_width = i2s->slot_width;
|
||||
+
|
||||
bclk_parent_rate = i2s->variant->get_bclk_parent_rate(i2s);
|
||||
bclk_div = sun4i_i2s_get_bclk_div(i2s, bclk_parent_rate,
|
||||
rate, slots, slot_width);
|
||||
--
|
||||
2.24.0
|
||||
|
|
@ -44,53 +44,11 @@ index c21f2331add6..8161895dde52 100644
|
|||
vcc-hdmi-supply = <®_dldo1>;
|
||||
};
|
||||
|
||||
+&sound_hdmi {
|
||||
+&hdmi_sound {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&uart0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&uart0_pins_a>;
|
||||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
|
||||
index 0f69f3593975..0b44018361cb 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
|
||||
@@ -727,6 +727,35 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
+ i2s2: i2s@1c22800 {
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ compatible = "allwinner,sun8i-h3-i2s";
|
||||
+ reg = <0x01c22800 0x400>;
|
||||
+ interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ clocks = <&ccu CLK_BUS_I2S2>, <&ccu CLK_I2S2>;
|
||||
+ clock-names = "apb", "mod";
|
||||
+ dmas = <&dma 27>;
|
||||
+ resets = <&ccu RST_BUS_I2S2>;
|
||||
+ dma-names = "tx";
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ sound_hdmi: sound_hdmi {
|
||||
+ compatible = "simple-audio-card";
|
||||
+ simple-audio-card,format = "i2s";
|
||||
+ simple-audio-card,name = "allwinner,hdmi";
|
||||
+ simple-audio-card,mclk-fs = <256>;
|
||||
+ status = "disabled";
|
||||
+
|
||||
+ simple-audio-card,codec {
|
||||
+ sound-dai = <&hdmi>;
|
||||
+ };
|
||||
+
|
||||
+ simple-audio-card,cpu {
|
||||
+ sound-dai = <&i2s2>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
rtc: rtc@1f00000 {
|
||||
compatible = "allwinner,sun6i-a31-rtc";
|
||||
reg = <0x01f00000 0x54>;
|
||||
--
|
||||
2.17.1
|
||||
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
From 887b96d878bb0e261bc19062dc73d193c75bc56a Mon Sep 17 00:00:00 2001
|
||||
From: Vasily Khoruzhick <anarsoul@gmail.com>
|
||||
Date: Tue, 26 Dec 2017 15:53:53 -0800
|
||||
Subject: [PATCH 008/146] arm64: dts: sun50i-a64-pine64: add HDMI audio nodes
|
||||
|
||||
Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com>
|
||||
---
|
||||
arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
|
||||
index d06b5b88f60e..8c5dd99cc9ac 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
|
||||
@@ -97,6 +97,10 @@
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
+&i2s2 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&mdio {
|
||||
ext_rmii_phy1: ethernet-phy@1 {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
@@ -254,6 +258,10 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
+&sound_hdmi {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
/* On Exp and Euler connectors */
|
||||
&uart0 {
|
||||
pinctrl-names = "default";
|
||||
--
|
||||
2.17.1
|
||||
|
|
@ -2,19 +2,6 @@ diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/
|
|||
index dc785da9c..141fd186b 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
@@ -113,6 +113,12 @@
|
||||
clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
};
|
||||
|
||||
+ opp@1640000000 {
|
||||
+ opp-hz = /bits/ 64 <1640000000>;
|
||||
+ opp-microvolt = <1160000 1160000 1160000>;
|
||||
+ clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
+ };
|
||||
+
|
||||
opp@1800000000 {
|
||||
opp-hz = /bits/ 64 <1800000000>;
|
||||
opp-microvolt = <1160000 1160000 1160000>;
|
||||
@@ -374,6 +381,17 @@
|
||||
#dma-cells = <1>;
|
||||
};
|
||||
|
@ -49,23 +36,6 @@ index dc785da9c..141fd186b 100644
|
|||
mmc2_pins: mmc2-pins {
|
||||
pins = "PC1", "PC4", "PC5", "PC6",
|
||||
"PC7", "PC8", "PC9", "PC10",
|
||||
@@ -318,6 +364,16 @@
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
+ spi0_pins: spi0-pins {
|
||||
+ pins = "PC2", "PC3", "PC0", "PC5";
|
||||
+ function = "spi0";
|
||||
+ };
|
||||
+
|
||||
+ spi1_pins: spi1-pins {
|
||||
+ pins = "PH5", "PH6", "PH4", "PH3";
|
||||
+ function = "spi1";
|
||||
+ };
|
||||
+
|
||||
uart0_ph_pins: uart0-ph-pins {
|
||||
pins = "PH0", "PH1";
|
||||
function = "uart0";
|
||||
@@ -511,17 +540,26 @@
|
||||
pins = "PG8", "PG9";
|
||||
function = "uart1";
|
||||
|
@ -103,45 +73,6 @@ index dc785da9c..141fd186b 100644
|
|||
};
|
||||
|
||||
mmc0: mmc@4020000 {
|
||||
@@ -391,6 +495,38 @@
|
||||
#size-cells = <0>;
|
||||
};
|
||||
|
||||
+ spi0: spi@5010000 {
|
||||
+ compatible = "allwinner,sun8i-h3-spi";
|
||||
+ reg = <0x05010000 0x1000>;
|
||||
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ clocks = <&ccu CLK_BUS_SPI0>, <&ccu CLK_SPI0>;
|
||||
+ clock-names = "ahb", "mod";
|
||||
+ dmas = <&dma 22>, <&dma 22>;
|
||||
+ dma-names = "rx", "tx";
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&spi0_pins>;
|
||||
+ resets = <&ccu RST_BUS_SPI0>;
|
||||
+ status = "disabled";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ };
|
||||
+
|
||||
+ spi1: spi@5011000 {
|
||||
+ compatible = "allwinner,sun8i-h3-spi";
|
||||
+ reg = <0x05011000 0x1000>;
|
||||
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ clocks = <&ccu CLK_BUS_SPI1>, <&ccu CLK_SPI1>;
|
||||
+ clock-names = "ahb", "mod";
|
||||
+ dmas = <&dma 23>, <&dma 23>;
|
||||
+ dma-names = "rx", "tx";
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&spi1_pins>;
|
||||
+ resets = <&ccu RST_BUS_SPI1>;
|
||||
+ status = "disabled";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ };
|
||||
+
|
||||
uart0: serial@5000000 {
|
||||
compatible = "snps,dw-apb-uart";
|
||||
reg = <0x05000000 0x400>;
|
||||
@@ -963,6 +1033,19 @@
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,78 +0,0 @@
|
|||
From e7623ac862573d231eea2ec77d393adbf2db3392 Mon Sep 17 00:00:00 2001
|
||||
From: Jagan Teki <jagan@amarulasolutions.com>
|
||||
Date: Tue, 4 Sep 2018 12:40:53 +0800
|
||||
Subject: [PATCH 101/146] arm64: dts: allwinner: a64: Enable HDMI output on A64
|
||||
boards w/ HDMI
|
||||
|
||||
Enable all necessary device tree nodes and add connector node to device
|
||||
trees for all supported A64 boards with HDMI.
|
||||
|
||||
Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
|
||||
[Icenowy: squash all board patches altogether and change supply name]
|
||||
Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
|
||||
Tested-by: Jagan Teki <jagan@amarulasolutions.com> # BPI-M64, OPI-Win,
|
||||
Tested-by: Vasily Khoruzhick <anarsoul@gmail.com>
|
||||
---
|
||||
.../dts/allwinner/sun50i-a64-bananapi-m64.dts | 26 ++++++++++++++++++
|
||||
.../dts/allwinner/sun50i-a64-nanopi-a64.dts | 27 +++++++++++++++++++
|
||||
.../dts/allwinner/sun50i-a64-olinuxino.dts | 26 ++++++++++++++++++
|
||||
.../dts/allwinner/sun50i-a64-orangepi-win.dts | 27 +++++++++++++++++++
|
||||
.../boot/dts/allwinner/sun50i-a64-pine64.dts | 27 +++++++++++++++++++
|
||||
.../dts/allwinner/sun50i-a64-pinebook.dts | 26 ++++++++++++++++++
|
||||
.../allwinner/sun50i-a64-sopine-baseboard.dts | 26 ++++++++++++++++++
|
||||
7 files changed, 185 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts
|
||||
index b3698a8bb1d3..52cbb3052588 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts
|
||||
@@ -53,6 +53,17 @@
|
||||
};
|
||||
};
|
||||
|
||||
+ hdmi-connector {
|
||||
+ compatible = "hdmi-connector";
|
||||
+ type = "a";
|
||||
+
|
||||
+ port {
|
||||
+ hdmi_con_in: endpoint {
|
||||
+ remote-endpoint = <&hdmi_out_con>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
reg_vcc3v3: vcc3v3 {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "vcc3v3";
|
||||
@@ -70,6 +81,10 @@
|
||||
cpu-supply = <®_dcdc2>;
|
||||
};
|
||||
|
||||
+&de {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&ehci0 {
|
||||
phys = <&usbphy 0>;
|
||||
phy-names = "usb";
|
||||
@@ -80,6 +95,17 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+&hdmi {
|
||||
+ hvcc-supply = <®_dldo1>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&hdmi_out {
|
||||
+ hdmi_out_con: endpoint {
|
||||
+ remote-endpoint = <&hdmi_con_in>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
&mmc0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&mmc0_pins>;
|
||||
--
|
||||
2.17.1
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
From c66953710d4c7205c380bf9c5a7e296bef3d4948 Mon Sep 17 00:00:00 2001
|
||||
From: Icenowy Zheng <icenowy@aosc.io>
|
||||
Date: Thu, 18 Oct 2018 15:33:19 +0800
|
||||
Subject: [PATCH 126/146] drm/bridge: move ANA78xx driver to analogix
|
||||
subdirectory
|
||||
|
||||
As ANA78xx chips are designed and produced by Analogix Semiconductor,
|
||||
Inc, move their driver codes into analogix subdirectory.
|
||||
|
||||
Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
|
||||
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
|
||||
---
|
||||
drivers/gpu/drm/bridge/Kconfig | 10 ----------
|
||||
drivers/gpu/drm/bridge/Makefile | 4 ++--
|
||||
drivers/gpu/drm/bridge/analogix/Kconfig | 10 ++++++++++
|
||||
drivers/gpu/drm/bridge/analogix/Makefile | 1 +
|
||||
.../gpu/drm/bridge/{ => analogix}/analogix-anx78xx.c | 0
|
||||
.../gpu/drm/bridge/{ => analogix}/analogix-anx78xx.h | 0
|
||||
6 files changed, 13 insertions(+), 12 deletions(-)
|
||||
rename drivers/gpu/drm/bridge/{ => analogix}/analogix-anx78xx.c (100%)
|
||||
rename drivers/gpu/drm/bridge/{ => analogix}/analogix-anx78xx.h (100%)
|
||||
|
||||
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
|
||||
index 4934fcf..729a806 100644
|
||||
--- a/drivers/gpu/drm/bridge/Makefile
|
||||
+++ b/drivers/gpu/drm/bridge/Makefile
|
||||
@@ -1,5 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
-obj-$(CONFIG_DRM_ANALOGIX_ANX78XX) += analogix-anx78xx.o
|
||||
obj-$(CONFIG_DRM_CDNS_DSI) += cdns-dsi.o
|
||||
obj-$(CONFIG_DRM_DUMB_VGA_DAC) += dumb-vga-dac.o
|
||||
obj-$(CONFIG_DRM_LVDS_ENCODER) += lvds-encoder.o
|
|
@ -230,7 +230,7 @@ index 000000000000..9cb30962032e
|
|||
+#include <linux/regmap.h>
|
||||
+
|
||||
+#include <drm/drm.h>
|
||||
+#include <drm/drmP.h>
|
||||
+#include <drm/drm_drv.h>
|
||||
+#include <drm/drm_dp_helper.h>
|
||||
+
|
||||
+#include "analogix-i2c-dptx.h"
|
|
@ -52,7 +52,7 @@ new file mode 100644
|
|||
index 000000000000..81676407aa6d
|
||||
--- /dev/null
|
||||
+++ b/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c
|
||||
@@ -0,0 +1,862 @@
|
||||
@@ -0,0 +1,863 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0
|
||||
+/*
|
||||
+ * Copyright(c) Icenowy Zheng <icenowy@aosc.io>
|
||||
|
@ -72,10 +72,11 @@ index 000000000000..81676407aa6d
|
|||
+#include <linux/gpio/consumer.h>
|
||||
+#include <linux/regulator/consumer.h>
|
||||
+
|
||||
+#include <drm/drmP.h>
|
||||
+#include <drm/drm_drv.h>
|
||||
+#include <drm/drm_atomic_helper.h>
|
||||
+#include <drm/drm_crtc.h>
|
||||
+#include <drm/drm_crtc_helper.h>
|
||||
+#include <drm/drm_probe_helper.h>
|
||||
+#include <drm/drm_dp_helper.h>
|
||||
+#include <drm/drm_edid.h>
|
||||
+
|
||||
|
@ -603,7 +604,7 @@ index 000000000000..81676407aa6d
|
|||
+ if (!anx6345->edid) {
|
||||
+ err = anx6345_probe_edid_from_of(anx6345);
|
||||
+ if (err) {
|
||||
+ DRM_ERROR("Failed to probe EDID from device tree: %d\n", err);
|
||||
+ DRM_ERROR("Failed to probe EDID from device tree: &d\n", err);
|
||||
+ goto unlock;
|
||||
+ }
|
||||
+ }
|
||||
|
@ -716,8 +717,8 @@ index 000000000000..81676407aa6d
|
|||
+}
|
||||
+
|
||||
+static void anx6345_bridge_mode_set(struct drm_bridge *bridge,
|
||||
+ struct drm_display_mode *mode,
|
||||
+ struct drm_display_mode *adjusted_mode)
|
||||
+ const struct drm_display_mode *mode,
|
||||
+ const struct drm_display_mode *adjusted_mode)
|
||||
+{
|
||||
+ struct anx6345 *anx6345 = bridge_to_anx6345(bridge);
|
||||
+
|
|
@ -1,24 +0,0 @@
|
|||
From 2c38da8ed7cc1f7dabe72c4d455ba25e0ba18fe7 Mon Sep 17 00:00:00 2001
|
||||
From: Vasily Khoruzhick <anarsoul@gmail.com>
|
||||
Date: Sun, 28 Oct 2018 19:06:28 -0700
|
||||
Subject: [PATCH 136/146] hdmi audio fixup
|
||||
|
||||
---
|
||||
arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
|
||||
index 0f5b412cfc81..f507bb1d8c3d 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
|
||||
@@ -1044,6 +1044,7 @@
|
||||
};
|
||||
|
||||
hdmi: hdmi@1ee0000 {
|
||||
+ #sound-dai-cells = <0>;
|
||||
compatible = "allwinner,sun50i-a64-dw-hdmi",
|
||||
"allwinner,sun8i-a83t-dw-hdmi";
|
||||
reg = <0x01ee0000 0x10000>;
|
||||
--
|
||||
2.17.1
|
||||
|
|
@ -27,7 +27,7 @@ index 8c9bd4dfbbba..0f788400ece0 100644
|
|||
"MIC2", "Internal Microphone Right";
|
||||
};
|
||||
|
||||
+&sound_hdmi {
|
||||
+&hdmi_sound {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
|
@ -1,54 +0,0 @@
|
|||
From e4a72ee5f7717daaa2928b3d18a5327739c8b180 Mon Sep 17 00:00:00 2001
|
||||
From: Vasily Khoruzhick <anarsoul@gmail.com>
|
||||
Date: Wed, 31 Oct 2018 19:40:18 -0700
|
||||
Subject: [PATCH 139/146] Bluetooth: Add new quirk for broken local ext
|
||||
features max_page
|
||||
|
||||
Some adapters (e.g. RTL8723CS) advertise that they have more than
|
||||
2 pages for local ext features, but they don't support any features
|
||||
declared in these pages. RTL8723CS reports max_page = 2 and declares
|
||||
support for sync train and secure connection, but it responds with
|
||||
either garbage or with error in status on corresponding commands.
|
||||
|
||||
Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com>
|
||||
---
|
||||
include/net/bluetooth/hci.h | 7 +++++++
|
||||
net/bluetooth/hci_event.c | 4 +++-
|
||||
2 files changed, 10 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
|
||||
index cdd9f1fe7cfa..32b9195f6fca 100644
|
||||
--- a/include/net/bluetooth/hci.h
|
||||
+++ b/include/net/bluetooth/hci.h
|
||||
@@ -192,6 +192,13 @@ enum {
|
||||
*
|
||||
*/
|
||||
HCI_QUIRK_NON_PERSISTENT_SETUP,
|
||||
+
|
||||
+ /* When this quirk is set, max_page for local extended features
|
||||
+ * is set to 1, even if controller reports higher number. Some
|
||||
+ * controllers (e.g. RTL8723CS) report more pages, but they
|
||||
+ * don't actually support features declared there.
|
||||
+ */
|
||||
+ HCI_QUIRK_BROKEN_LOCAL_EXT_FTR_MAX_PAGE,
|
||||
};
|
||||
|
||||
/* HCI device flags */
|
||||
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
|
||||
index f12555f23a49..3eb289711dea 100644
|
||||
--- a/net/bluetooth/hci_event.c
|
||||
+++ b/net/bluetooth/hci_event.c
|
||||
@@ -639,7 +639,9 @@ static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
|
||||
if (rp->status)
|
||||
return;
|
||||
|
||||
- if (hdev->max_page < rp->max_page)
|
||||
+ if (!test_bit(HCI_QUIRK_BROKEN_LOCAL_EXT_FTR_MAX_PAGE,
|
||||
+ &hdev->quirks) &&
|
||||
+ hdev->max_page < rp->max_page)
|
||||
hdev->max_page = rp->max_page;
|
||||
|
||||
if (rp->page < HCI_MAX_PAGES)
|
||||
--
|
||||
2.17.1
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
From e8a404daea8d869304fdf810ac502cda8fbb4999 Mon Sep 17 00:00:00 2001
|
||||
From: Vasily Khoruzhick <anarsoul@gmail.com>
|
||||
Date: Wed, 31 Oct 2018 19:48:25 -0700
|
||||
Subject: [PATCH 140/146] Bluetooth: hci_h5: Add support for reset GPIO
|
||||
|
||||
Some boards (e.g. Pine64 and Pinebook) wire a GPIO to reset pin of
|
||||
RTL8723BS
|
||||
|
||||
Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com>
|
||||
---
|
||||
drivers/bluetooth/hci_h5.c | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c
|
||||
index 8eede1197cd2..6e047df4f475 100644
|
||||
--- a/drivers/bluetooth/hci_h5.c
|
||||
+++ b/drivers/bluetooth/hci_h5.c
|
||||
@@ -107,6 +107,7 @@ struct h5 {
|
||||
const struct h5_vnd *vnd;
|
||||
const char *id;
|
||||
|
||||
+ struct gpio_desc *reset_gpio;
|
||||
struct gpio_desc *enable_gpio;
|
||||
struct gpio_desc *device_wake_gpio;
|
||||
};
|
||||
@@ -831,6 +832,10 @@ static int h5_serdev_probe(struct serdev_device *serdev)
|
||||
if (IS_ERR(h5->device_wake_gpio))
|
||||
return PTR_ERR(h5->device_wake_gpio);
|
||||
|
||||
+ h5->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
|
||||
+ if (IS_ERR(h5->reset_gpio))
|
||||
+ return PTR_ERR(h5->reset_gpio);
|
||||
+
|
||||
return hci_uart_register_device(&h5->serdev_hu, &h5p);
|
||||
}
|
||||
|
||||
@@ -897,6 +902,9 @@ static void h5_btrtl_open(struct h5 *h5)
|
||||
|
||||
/* The controller needs up to 500ms to wakeup */
|
||||
gpiod_set_value_cansleep(h5->enable_gpio, 1);
|
||||
+ /* Take it out of reset */
|
||||
+ gpiod_set_value_cansleep(h5->reset_gpio, 0);
|
||||
+ msleep(100);
|
||||
gpiod_set_value_cansleep(h5->device_wake_gpio, 1);
|
||||
msleep(500);
|
||||
}
|
||||
@@ -904,6 +912,7 @@ static void h5_btrtl_open(struct h5 *h5)
|
||||
static void h5_btrtl_close(struct h5 *h5)
|
||||
{
|
||||
gpiod_set_value_cansleep(h5->device_wake_gpio, 0);
|
||||
+ gpiod_set_value_cansleep(h5->reset_gpio, 1);
|
||||
gpiod_set_value_cansleep(h5->enable_gpio, 0);
|
||||
}
|
||||
|
||||
--
|
||||
2.17.1
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
From 38caa52f547c63c9cd7aa19259bb6806cff7d50d Mon Sep 17 00:00:00 2001
|
||||
From: Vasily Khoruzhick <anarsoul@gmail.com>
|
||||
Date: Wed, 31 Oct 2018 20:07:41 -0700
|
||||
Subject: [PATCH 142/146] Bluetooth: hci_h5: Add support for binding RTL8723BS
|
||||
with device tree
|
||||
|
||||
RTL8723BS is often used in ARM boards, so add ability to bind it
|
||||
using device tree.
|
||||
|
||||
Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com>
|
||||
---
|
||||
drivers/bluetooth/hci_h5.c | 20 ++++++++++++++++++++
|
||||
1 file changed, 20 insertions(+)
|
||||
|
||||
diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c
|
||||
index 6e047df4f475..9cc10e299fa8 100644
|
||||
--- a/drivers/bluetooth/hci_h5.c
|
||||
+++ b/drivers/bluetooth/hci_h5.c
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
+#include <linux/of_device.h>
|
||||
#include <linux/serdev.h>
|
||||
#include <linux/skbuff.h>
|
||||
|
||||
@@ -821,6 +822,11 @@ static int h5_serdev_probe(struct serdev_device *serdev)
|
||||
if (h5->vnd->acpi_gpio_map)
|
||||
devm_acpi_dev_add_driver_gpios(dev,
|
||||
h5->vnd->acpi_gpio_map);
|
||||
+ } else {
|
||||
+ h5->vnd = (const struct h5_vnd *)
|
||||
+ of_device_get_match_data(&serdev->dev);
|
||||
+ of_property_read_string(serdev->dev.of_node,
|
||||
+ "firmware-postfix", &h5->id);
|
||||
}
|
||||
|
||||
h5->enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW);
|
||||
@@ -944,13 +950,27 @@ static const struct acpi_device_id h5_acpi_match[] = {
|
||||
MODULE_DEVICE_TABLE(acpi, h5_acpi_match);
|
||||
#endif
|
||||
|
||||
+static struct h5_vnd rtl8723_of_vnd = {
|
||||
+ .setup = h5_btrtl_setup,
|
||||
+ .open = h5_btrtl_open,
|
||||
+ .close = h5_btrtl_close,
|
||||
+};
|
||||
+
|
||||
+static const struct of_device_id h5_of_match[] = {
|
||||
+ { .compatible = "realtek,rtl8723bs-bt", .data = &rtl8723_of_vnd },
|
||||
+ { .compatible = "realtek,rtl8723cs-bt", .data = &rtl8723_of_vnd },
|
||||
+ { /* sentinel */ },
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, h5_of_match);
|
||||
+
|
||||
static struct serdev_device_driver h5_serdev_driver = {
|
||||
.probe = h5_serdev_probe,
|
||||
.remove = h5_serdev_remove,
|
||||
.driver = {
|
||||
.name = "hci_uart_h5",
|
||||
.acpi_match_table = ACPI_PTR(h5_acpi_match),
|
||||
.pm = &h5_serdev_pm_ops,
|
||||
+ .of_match_table = of_match_ptr(h5_of_match),
|
||||
},
|
||||
};
|
||||
|
||||
--
|
||||
2.17.1
|
||||
|
|
@ -1,311 +0,0 @@
|
|||
From 08c47cbb508e40e5e404055f77653474d5793e27 Mon Sep 17 00:00:00 2001
|
||||
From: Vasily Khoruzhick <anarsoul@gmail.com>
|
||||
Date: Wed, 31 Oct 2018 20:33:22 -0700
|
||||
Subject: [PATCH 143/146] Bluetooth: btrtl: add support for the RTL8723CS
|
||||
|
||||
The Realtek RTL8723CS is SDIO WiFi chip. It also contains a Bluetooth
|
||||
module which is connected via UART to the host.
|
||||
|
||||
It shares lmp subversion with 8703B, so Realtek's userspace
|
||||
initialization tool (rtk_hciattach) differentiates varieties of RTL8723CS
|
||||
(CG, VF, XX) with RTL8703B using vendor's command to read chip type.
|
||||
|
||||
Also this chip declares support for some features it doesn't support
|
||||
so add a quirk to indicate that these features are broken.
|
||||
|
||||
Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com>
|
||||
---
|
||||
drivers/bluetooth/btrtl.c | 128 ++++++++++++++++++++++++++++++++++++-
|
||||
drivers/bluetooth/btrtl.h | 12 ++++
|
||||
drivers/bluetooth/hci_h5.c | 4 ++
|
||||
3 files changed, 141 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/bluetooth/btrtl.c b/drivers/bluetooth/btrtl.c
|
||||
index 7f9ea8e4c1b2..f9474e78bcfa 100644
|
||||
--- a/drivers/bluetooth/btrtl.c
|
||||
+++ b/drivers/bluetooth/btrtl.c
|
||||
@@ -27,8 +27,12 @@
|
||||
|
||||
#define VERSION "0.1"
|
||||
|
||||
+#define RTL_CHIP_8723CS_CG 3
|
||||
+#define RTL_CHIP_8723CS_VF 4
|
||||
+#define RTL_CHIP_8723CS_XX 5
|
||||
#define RTL_EPATCH_SIGNATURE "Realtech"
|
||||
#define RTL_ROM_LMP_3499 0x3499
|
||||
+#define RTL_ROM_LMP_8703B 0x8703
|
||||
#define RTL_ROM_LMP_8723A 0x1200
|
||||
#define RTL_ROM_LMP_8723B 0x8723
|
||||
#define RTL_ROM_LMP_8821A 0x8821
|
||||
@@ -40,6 +44,7 @@
|
||||
#define IC_MATCH_FL_HCIREV (1 << 1)
|
||||
#define IC_MATCH_FL_HCIVER (1 << 2)
|
||||
#define IC_MATCH_FL_HCIBUS (1 << 3)
|
||||
+#define IC_MATCH_FL_CHIP_TYPE (1 << 4)
|
||||
#define IC_INFO(lmps, hcir) \
|
||||
.match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_HCIREV, \
|
||||
.lmp_subver = (lmps), \
|
||||
@@ -51,6 +56,7 @@ struct id_table {
|
||||
__u16 hci_rev;
|
||||
__u8 hci_ver;
|
||||
__u8 hci_bus;
|
||||
+ __u8 chip_type;
|
||||
bool config_needed;
|
||||
bool has_rom_version;
|
||||
char *fw_name;
|
||||
@@ -98,6 +104,39 @@ static const struct id_table ic_id_table[] = {
|
||||
.fw_name = "rtl_bt/rtl8723b_fw.bin",
|
||||
.cfg_name = "rtl_bt/rtl8723b_config" },
|
||||
|
||||
+ /* 8723CS-CG */
|
||||
+ { .match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_CHIP_TYPE |
|
||||
+ IC_MATCH_FL_HCIBUS,
|
||||
+ .lmp_subver = RTL_ROM_LMP_8703B,
|
||||
+ .chip_type = RTL_CHIP_8723CS_CG,
|
||||
+ .hci_bus = HCI_UART,
|
||||
+ .config_needed = true,
|
||||
+ .has_rom_version = true,
|
||||
+ .fw_name = "rtl_bt/rtl8723cs_cg_fw.bin",
|
||||
+ .cfg_name = "rtl_bt/rtl8723cs_cg_config" },
|
||||
+
|
||||
+ /* 8723CS-VF */
|
||||
+ { .match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_CHIP_TYPE |
|
||||
+ IC_MATCH_FL_HCIBUS,
|
||||
+ .lmp_subver = RTL_ROM_LMP_8703B,
|
||||
+ .chip_type = RTL_CHIP_8723CS_VF,
|
||||
+ .hci_bus = HCI_UART,
|
||||
+ .config_needed = true,
|
||||
+ .has_rom_version = true,
|
||||
+ .fw_name = "rtl_bt/rtl8723cs_vf_fw.bin",
|
||||
+ .cfg_name = "rtl_bt/rtl8723cs_vf_config" },
|
||||
+
|
||||
+ /* 8723CS-XX */
|
||||
+ { .match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_CHIP_TYPE |
|
||||
+ IC_MATCH_FL_HCIBUS,
|
||||
+ .lmp_subver = RTL_ROM_LMP_8703B,
|
||||
+ .chip_type = RTL_CHIP_8723CS_XX,
|
||||
+ .hci_bus = HCI_UART,
|
||||
+ .config_needed = true,
|
||||
+ .has_rom_version = true,
|
||||
+ .fw_name = "rtl_bt/rtl8723cs_xx_fw.bin",
|
||||
+ .cfg_name = "rtl_bt/rtl8723cs_xx_config" },
|
||||
+
|
||||
/* 8723D */
|
||||
{ IC_INFO(RTL_ROM_LMP_8723B, 0xd),
|
||||
.config_needed = true,
|
||||
@@ -147,7 +186,8 @@ static const struct id_table ic_id_table[] = {
|
||||
};
|
||||
|
||||
static const struct id_table *btrtl_match_ic(u16 lmp_subver, u16 hci_rev,
|
||||
- u8 hci_ver, u8 hci_bus)
|
||||
+ u8 hci_ver, u8 hci_bus,
|
||||
+ u8 chip_type)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -164,6 +204,9 @@ static const struct id_table *btrtl_match_ic(u16 lmp_subver, u16 hci_rev,
|
||||
if ((ic_id_table[i].match_flags & IC_MATCH_FL_HCIBUS) &&
|
||||
(ic_id_table[i].hci_bus != hci_bus))
|
||||
continue;
|
||||
+ if ((ic_id_table[i].match_flags & IC_MATCH_FL_CHIP_TYPE) &&
|
||||
+ (ic_id_table[i].chip_type != chip_type))
|
||||
+ continue;
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -225,6 +268,7 @@ static int rtlbt_parse_firmware(struct hci_dev *hdev,
|
||||
{ RTL_ROM_LMP_8723B, 1 },
|
||||
{ RTL_ROM_LMP_8821A, 2 },
|
||||
{ RTL_ROM_LMP_8761A, 3 },
|
||||
+ { RTL_ROM_LMP_8703B, 7 },
|
||||
{ RTL_ROM_LMP_8822B, 8 },
|
||||
{ RTL_ROM_LMP_8723B, 9 }, /* 8723D */
|
||||
{ RTL_ROM_LMP_8821A, 10 }, /* 8821C */
|
||||
@@ -499,6 +543,48 @@ static struct sk_buff *btrtl_read_local_version(struct hci_dev *hdev)
|
||||
return skb;
|
||||
}
|
||||
|
||||
+static bool rtl_has_chip_type(u16 lmp_subver)
|
||||
+{
|
||||
+ switch (lmp_subver) {
|
||||
+ case RTL_ROM_LMP_8703B:
|
||||
+ return true;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+static int rtl_read_chip_type(struct hci_dev *hdev, u8 *type)
|
||||
+{
|
||||
+ struct rtl_chip_type_evt *chip_type;
|
||||
+ struct sk_buff *skb;
|
||||
+ const unsigned char cmd_buf[] = {0x00, 0x94, 0xa0, 0x00, 0xb0};
|
||||
+
|
||||
+ /* Read RTL chip type command */
|
||||
+ skb = __hci_cmd_sync(hdev, 0xfc61, 5, cmd_buf, HCI_INIT_TIMEOUT);
|
||||
+ if (IS_ERR(skb)) {
|
||||
+ rtl_dev_err(hdev, "Read chip type failed (%ld)",
|
||||
+ PTR_ERR(skb));
|
||||
+ return PTR_ERR(skb);
|
||||
+ }
|
||||
+
|
||||
+ if (skb->len != sizeof(*chip_type)) {
|
||||
+ rtl_dev_err(hdev, "RTL chip type event length mismatch");
|
||||
+ kfree_skb(skb);
|
||||
+ return -EIO;
|
||||
+ }
|
||||
+
|
||||
+ chip_type = (struct rtl_chip_type_evt *)skb->data;
|
||||
+ rtl_dev_info(hdev, "chip_type status=%x type=%x",
|
||||
+ chip_type->status, chip_type->type);
|
||||
+
|
||||
+ *type = chip_type->type & 0x0f;
|
||||
+
|
||||
+ kfree_skb(skb);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
void btrtl_free(struct btrtl_device_info *btrtl_dev)
|
||||
{
|
||||
kfree(btrtl_dev->fw_data);
|
||||
@@ -515,7 +601,7 @@ struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev,
|
||||
struct hci_rp_read_local_version *resp;
|
||||
char cfg_name[40];
|
||||
u16 hci_rev, lmp_subver;
|
||||
- u8 hci_ver;
|
||||
+ u8 hci_ver, chip_type = 0;
|
||||
int ret;
|
||||
|
||||
btrtl_dev = kzalloc(sizeof(*btrtl_dev), GFP_KERNEL);
|
||||
@@ -540,8 +626,14 @@ struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev,
|
||||
lmp_subver = le16_to_cpu(resp->lmp_subver);
|
||||
kfree_skb(skb);
|
||||
|
||||
+ if (rtl_has_chip_type(lmp_subver)) {
|
||||
+ ret = rtl_read_chip_type(hdev, &chip_type);
|
||||
+ if (ret)
|
||||
+ goto err_free;
|
||||
+ }
|
||||
+
|
||||
btrtl_dev->ic_info = btrtl_match_ic(lmp_subver, hci_rev, hci_ver,
|
||||
- hdev->bus);
|
||||
+ hdev->bus, chip_type);
|
||||
|
||||
if (!btrtl_dev->ic_info) {
|
||||
rtl_dev_err(hdev, "rtl: unknown IC info, lmp subver %04x, hci rev %04x, hci ver %04x",
|
||||
@@ -610,6 +702,7 @@ int btrtl_download_firmware(struct hci_dev *hdev,
|
||||
case RTL_ROM_LMP_8821A:
|
||||
case RTL_ROM_LMP_8761A:
|
||||
case RTL_ROM_LMP_8822B:
|
||||
+ case RTL_ROM_LMP_8703B:
|
||||
return btrtl_setup_rtl8723b(hdev, btrtl_dev);
|
||||
default:
|
||||
rtl_dev_info(hdev, "rtl: assuming no firmware upload needed\n");
|
||||
@@ -628,7 +721,12 @@ int btrtl_setup_realtek(struct hci_dev *hdev)
|
||||
return PTR_ERR(btrtl_dev);
|
||||
|
||||
ret = btrtl_download_firmware(hdev, btrtl_dev);
|
||||
+ if (ret)
|
||||
+ goto out_free;
|
||||
|
||||
+ btrtl_apply_quirks(hdev, btrtl_dev);
|
||||
+
|
||||
+out_free:
|
||||
btrtl_free(btrtl_dev);
|
||||
|
||||
return ret;
|
||||
@@ -743,6 +841,24 @@ int btrtl_get_uart_settings(struct hci_dev *hdev,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(btrtl_get_uart_settings);
|
||||
|
||||
+void btrtl_apply_quirks(struct hci_dev *hdev,
|
||||
+ struct btrtl_device_info *btrtl_dev)
|
||||
+{
|
||||
+ switch (btrtl_dev->ic_info->lmp_subver) {
|
||||
+ case RTL_ROM_LMP_8703B:
|
||||
+ /* 8723CS reports two pages for local ext features,
|
||||
+ * but it doesn't support any features from page 2 -
|
||||
+ * it either responds with garbage or with error status
|
||||
+ */
|
||||
+ set_bit(HCI_QUIRK_BROKEN_LOCAL_EXT_FTR_MAX_PAGE,
|
||||
+ &hdev->quirks);
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(btrtl_apply_quirks);
|
||||
+
|
||||
MODULE_AUTHOR("Daniel Drake <drake@endlessm.com>");
|
||||
MODULE_DESCRIPTION("Bluetooth support for Realtek devices ver " VERSION);
|
||||
MODULE_VERSION(VERSION);
|
||||
@@ -752,6 +868,12 @@ MODULE_FIRMWARE("rtl_bt/rtl8723b_fw.bin");
|
||||
MODULE_FIRMWARE("rtl_bt/rtl8723b_config.bin");
|
||||
MODULE_FIRMWARE("rtl_bt/rtl8723bs_fw.bin");
|
||||
MODULE_FIRMWARE("rtl_bt/rtl8723bs_config.bin");
|
||||
+MODULE_FIRMWARE("rtl_bt/rtl8723cs_cg_fw.bin");
|
||||
+MODULE_FIRMWARE("rtl_bt/rtl8723cs_cg_config.bin");
|
||||
+MODULE_FIRMWARE("rtl_bt/rtl8723cs_vf_fw.bin");
|
||||
+MODULE_FIRMWARE("rtl_bt/rtl8723cs_vf_config.bin");
|
||||
+MODULE_FIRMWARE("rtl_bt/rtl8723cs_xx_fw.bin");
|
||||
+MODULE_FIRMWARE("rtl_bt/rtl8723cs_xx_config.bin");
|
||||
MODULE_FIRMWARE("rtl_bt/rtl8723ds_fw.bin");
|
||||
MODULE_FIRMWARE("rtl_bt/rtl8723ds_config.bin");
|
||||
MODULE_FIRMWARE("rtl_bt/rtl8761a_fw.bin");
|
||||
diff --git a/drivers/bluetooth/btrtl.h b/drivers/bluetooth/btrtl.h
|
||||
index f5e36f3993a8..db4e4a1542b7 100644
|
||||
--- a/drivers/bluetooth/btrtl.h
|
||||
+++ b/drivers/bluetooth/btrtl.h
|
||||
@@ -24,6 +24,11 @@
|
||||
|
||||
struct btrtl_device_info;
|
||||
|
||||
+struct rtl_chip_type_evt {
|
||||
+ __u8 status;
|
||||
+ __u8 type;
|
||||
+} __packed;
|
||||
+
|
||||
struct rtl_download_cmd {
|
||||
__u8 index;
|
||||
__u8 data[RTL_FRAG_LEN];
|
||||
@@ -69,6 +74,8 @@ int btrtl_get_uart_settings(struct hci_dev *hdev,
|
||||
struct btrtl_device_info *btrtl_dev,
|
||||
unsigned int *controller_baudrate,
|
||||
u32 *device_baudrate, bool *flow_control);
|
||||
+void btrtl_apply_quirks(struct hci_dev *hdev,
|
||||
+ struct btrtl_device_info *btrtl_dev);
|
||||
|
||||
#else
|
||||
|
||||
@@ -100,6 +107,11 @@ static inline int btrtl_get_uart_settings(struct hci_dev *hdev,
|
||||
bool *flow_control)
|
||||
{
|
||||
return -ENOENT;
|
||||
+
|
||||
+static inline void btrtl_apply_quirks(struct hci_dev *hdev,
|
||||
+ struct btrtl_device_info *btrtl_dev)
|
||||
+{
|
||||
+}
|
||||
}
|
||||
|
||||
#endif
|
||||
diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c
|
||||
index 9cc10e299fa8..7d72e092ce9d 100644
|
||||
--- a/drivers/bluetooth/hci_h5.c
|
||||
+++ b/drivers/bluetooth/hci_h5.c
|
||||
@@ -892,6 +892,10 @@ static int h5_btrtl_setup(struct h5 *h5)
|
||||
err = btrtl_download_firmware(h5->hu->hdev, btrtl_dev);
|
||||
/* Give the device some time before the hci-core sends it a reset */
|
||||
usleep_range(10000, 20000);
|
||||
+ if (err)
|
||||
+ goto out_free;
|
||||
+
|
||||
+ btrtl_apply_quirks(h5->hu->hdev, btrtl_dev);
|
||||
|
||||
out_free:
|
||||
btrtl_free(btrtl_dev);
|
||||
--
|
||||
2.17.1
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
Reverts Bluetooth: Make BT_HCIUART_RTL configuration option depend on ACPI
|
||||
|
||||
https://github.com/anarsoul/linux-2.6/commit/51474eff2bc2777061ab3658e014a37dc9d7a775
|
||||
|
||||
otherwise it breaks the compilation
|
||||
|
||||
diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig
|
||||
index 845b0314c..2df11cc08 100644
|
||||
--- a/drivers/bluetooth/Kconfig
|
||||
+++ b/drivers/bluetooth/Kconfig
|
||||
@@ -200,7 +200,6 @@ config BT_HCIUART_RTL
|
||||
depends on BT_HCIUART
|
||||
depends on BT_HCIUART_SERDEV
|
||||
depends on GPIOLIB
|
||||
- depends on ACPI
|
||||
select BT_HCIUART_3WIRE
|
||||
select BT_RTL
|
||||
help
|
|
@ -0,0 +1,26 @@
|
|||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
index f55879b..c3621dd 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
@@ -70,6 +80,13 @@
|
||||
clock-output-names = "osc24M";
|
||||
};
|
||||
|
||||
+ ext_osc32k: ext_osc32k_clk {
|
||||
+ #clock-cells = <0>;
|
||||
+ compatible = "fixed-clock";
|
||||
+ clock-frequency = <32768>;
|
||||
+ clock-output-names = "ext_osc32k";
|
||||
+ };
|
||||
+
|
||||
pmu {
|
||||
compatible = "arm,cortex-a53-pmu";
|
||||
interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
|
||||
@@ -922,6 +1050,7 @@
|
||||
interrupts = <5 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<6 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clock-output-names = "osc32k", "osc32k-out", "iosc";
|
||||
+ clocks = <&ext_osc32k>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
diff --git a/arch/arm/boot/dts/sun8i-r40.dtsi b/arch/arm/boot/dts/sun8i-r40.dtsi
|
||||
index 421dfbb..ae64248 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-r40.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun8i-r40.dtsi
|
||||
@@ -403,6 +420,11 @@
|
||||
function = "uart0";
|
||||
};
|
||||
|
||||
+ uart2_pi_pins: uart2-pi-pins {
|
||||
+ pins = "PI18", "PI19";
|
||||
+ function = "uart2";
|
||||
+ };
|
||||
+
|
||||
uart3_pg_pins: uart3-pg-pins {
|
||||
pins = "PG6", "PG7";
|
||||
function = "uart3";
|
||||
@@ -412,6 +463,23 @@
|
||||
pins = "PG8", "PG9";
|
||||
function = "uart3";
|
||||
};
|
||||
+
|
||||
+ uart4_ph_pins: uart4-ph-pins {
|
||||
+ pins = "PH4", "PH5";
|
||||
+ function = "uart4";
|
||||
+ };
|
||||
+
|
||||
+
|
||||
+ uart5_ph_pins: uart5-ph-pins {
|
||||
+ pins = "PH6", "PH7";
|
||||
+ function = "uart5";
|
||||
+ };
|
||||
+
|
||||
+ uart7_pi_pins: uart7-pi-pins {
|
||||
+ pins = "PI20", "PI21";
|
||||
+ function = "uart7";
|
||||
+ };
|
||||
+
|
||||
};
|
||||
|
||||
wdt: watchdog@1c20c90 {
|
|
@ -0,0 +1,84 @@
|
|||
diff --git a/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts b/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts
|
||||
index 42d62d1..35bba4e 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts
|
||||
@@ -305,6 +305,12 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+&uart2 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&uart2_pi_pins>;
|
||||
+ status = "disabled";
|
||||
+};
|
||||
+
|
||||
&uart3 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&uart3_pg_pins>, <&uart3_rts_cts_pg_pins>;
|
||||
@@ -324,6 +330,24 @@
|
||||
};
|
||||
};
|
||||
|
||||
+&uart4 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&uart4_ph_pins>;
|
||||
+ status = "disabled";
|
||||
+};
|
||||
+
|
||||
+&uart5 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&uart5_ph_pins>;
|
||||
+ status = "disabled";
|
||||
+};
|
||||
+
|
||||
+&uart7 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&uart7_pi_pins>;
|
||||
+ status = "disabled";
|
||||
+};
|
||||
+
|
||||
&usbphy {
|
||||
usb1_vbus-supply = <®_vcc5v0>;
|
||||
usb2_vbus-supply = <®_vcc5v0>;
|
||||
diff --git a/arch/arm/boot/dts/sun8i-v40-bananapi-m2-berry.dts b/arch/arm/boot/dts/sun8i-v40-bananapi-m2-berry.dts
|
||||
index 15c22b0..967833c 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-v40-bananapi-m2-berry.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-v40-bananapi-m2-berry.dts
|
||||
@@ -280,6 +280,12 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+&uart2 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&uart2_pi_pins>;
|
||||
+ status = "disabled";
|
||||
+};
|
||||
+
|
||||
&uart3 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&uart3_pg_pins>, <&uart3_rts_cts_pg_pins>;
|
||||
@@ -299,6 +305,24 @@
|
||||
};
|
||||
};
|
||||
|
||||
+&uart4 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&uart4_ph_pins>;
|
||||
+ status = "disabled";
|
||||
+};
|
||||
+
|
||||
+&uart5 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&uart5_ph_pins>;
|
||||
+ status = "disabled";
|
||||
+};
|
||||
+
|
||||
+&uart7 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&uart7_pi_pins>;
|
||||
+ status = "disabled";
|
||||
+};
|
||||
+
|
||||
&usbphy {
|
||||
usb1_vbus-supply = <®_vcc5v0>;
|
||||
status = "okay";
|
|
@ -48,7 +48,7 @@ index b8f46e2..24cb8b9 100644
|
|||
};
|
||||
};
|
||||
|
||||
+&sound_hdmi {
|
||||
+&hdmi_sound {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
|
|
|
@ -231,7 +231,7 @@ index 0000000..a6bf32d
|
|||
+ };
|
||||
+};
|
||||
+
|
||||
+&sound_hdmi {
|
||||
+&hdmi_sound {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
|
|
106
patch/kernel/sunxi-current/board-h6-improve-thermals.patch
Normal file
106
patch/kernel/sunxi-current/board-h6-improve-thermals.patch
Normal file
|
@ -0,0 +1,106 @@
|
|||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-cpu-opp.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6-cpu-opp.dtsi
|
||||
index bef3f50b1..90e4d1764 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-cpu-opp.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-cpu-opp.dtsi
|
||||
@@ -1,6 +1,7 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
// Copyright (C) 2020 Ondrej Jirman <megous@megous.com>
|
||||
// Copyright (C) 2020 Clément Péron <peron.clem@gmail.com>
|
||||
+// Copyright (C) 2020 Igor Pecovnik <igor@armbian.com>
|
||||
|
||||
/ {
|
||||
cpu_opp_table: cpu-opp-table {
|
||||
@@ -122,26 +123,67 @@
|
||||
|
||||
&cpu_thermal {
|
||||
trips {
|
||||
- cpu_hot_trip: cpu-hot {
|
||||
+ cpu_warm: cpu_warm {
|
||||
+ temperature = <75000>;
|
||||
+ hysteresis = <2000>;
|
||||
+ type = "passive";
|
||||
+ };
|
||||
+
|
||||
+ cpu_hot_pre: cpu_hot_pre {
|
||||
temperature = <80000>;
|
||||
hysteresis = <2000>;
|
||||
type = "passive";
|
||||
};
|
||||
+
|
||||
+ cpu_hot: cpu_hot {
|
||||
+ temperature = <85000>;
|
||||
+ hysteresis = <2000>;
|
||||
+ type = "passive";
|
||||
+ };
|
||||
+
|
||||
+ cpu_very_hot_pre: cpu_very_hot_pre {
|
||||
+ temperature = <90000>;
|
||||
+ hysteresis = <2000>;
|
||||
+ type = "passive";
|
||||
+ };
|
||||
|
||||
- cpu_very_hot_trip: cpu-very-hot {
|
||||
- temperature = <100000>;
|
||||
- hysteresis = <0>;
|
||||
+ cpu_very_hot: cpu_very_hot {
|
||||
+ temperature = <95000>;
|
||||
+ hysteresis = <2000>;
|
||||
+ type = "passive";
|
||||
+ };
|
||||
+
|
||||
+ cpu_crit: cpu_crit {
|
||||
+ temperature = <105000>;
|
||||
+ hysteresis = <2000>;
|
||||
type = "critical";
|
||||
};
|
||||
};
|
||||
|
||||
cooling-maps {
|
||||
- cpu-hot-limit {
|
||||
- trip = <&cpu_hot_trip>;
|
||||
- cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
|
||||
- <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
|
||||
- <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
|
||||
- <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
|
||||
+ cpu_warm_limit_cpu {
|
||||
+ trip = <&cpu_warm>;
|
||||
+ cooling-device = <&cpu0 THERMAL_NO_LIMIT 2>;
|
||||
+ };
|
||||
+
|
||||
+ cpu_hot_pre_limit_cpu {
|
||||
+ trip = <&cpu_hot_pre>;
|
||||
+ cooling-device = <&cpu0 2 3>;
|
||||
+ };
|
||||
+
|
||||
+ cpu_hot_limit_cpu {
|
||||
+ trip = <&cpu_hot>;
|
||||
+ cooling-device = <&cpu0 3 4>;
|
||||
+ };
|
||||
+
|
||||
+ cpu_very_hot_pre_limit_cpu {
|
||||
+ trip = <&cpu_very_hot_pre>;
|
||||
+ cooling-device = <&cpu0 5 6>;
|
||||
+ };
|
||||
+
|
||||
+ cpu_very_hot_limit_cpu {
|
||||
+ trip = <&cpu_very_hot>;
|
||||
+ cooling-device = <&cpu0 7 THERMAL_NO_LIMIT>;
|
||||
};
|
||||
};
|
||||
};
|
||||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
index 82cc1e5fe..00ebb89fc 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
|
||||
@@ -1147,8 +1147,9 @@
|
||||
|
||||
thermal-zones {
|
||||
cpu_thermal: cpu-thermal {
|
||||
- polling-delay-passive = <0>;
|
||||
- polling-delay = <0>;
|
||||
+ /* milliseconds */
|
||||
+ polling-delay-passive = <250>;
|
||||
+ polling-delay = <1000>;
|
||||
thermal-sensors = <&ths 0>;
|
||||
};
|
||||
|
|
@ -2,7 +2,7 @@ diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-lite2.dts b/arch/a
|
|||
index e098a2475..6c481b547 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-lite2.dts
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-lite2.dts
|
||||
@@ -3,9 +3,344 @@
|
||||
@@ -3,9 +3,350 @@
|
||||
* Copyright (C) 2018 Jagan Teki <jagan@openedev.com>
|
||||
*/
|
||||
|
||||
|
@ -98,6 +98,11 @@ index e098a2475..6c481b547 100644
|
|||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&gpu {
|
||||
+ mali-supply = <®_dcdcc>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&hdmi {
|
||||
+ status = "okay";
|
||||
+};
|
||||
|
@ -244,6 +249,7 @@ index e098a2475..6c481b547 100644
|
|||
+ };
|
||||
+
|
||||
+ reg_dcdcc: dcdcc {
|
||||
+ regulator-enable-ramp-delay = <32000>;
|
||||
+ regulator-min-microvolt = <810000>;
|
||||
+ regulator-max-microvolt = <1080000>;
|
||||
+ regulator-name = "vdd-gpu";
|
||||
|
|
|
@ -2,13 +2,6 @@ diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus2.dts b/a
|
|||
index e1ee1cd09..522a08d6c 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus2.dts
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus2.dts
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Jagan Teki <jteki@openedev.com>
|
||||
+ * Copyright (C) 2019 Adopted by Igor <igor@armbian.com>
|
||||
*
|
||||
* This file is dual-licensed: you can use it either under the terms
|
||||
* of the GPL or the X11 license, at your option. Note that this dual
|
||||
@@ -180,3 +181,12 @@
|
||||
pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>;
|
||||
status = "okay";
|
||||
|
|
7138
patch/kernel/sunxi-current/check/general-sunxi-overlays.patch
Normal file
7138
patch/kernel/sunxi-current/check/general-sunxi-overlays.patch
Normal file
File diff suppressed because it is too large
Load diff
|
@ -9,40 +9,60 @@ index 3c79f859..4e5c1d59 100644
|
|||
+*.dtb*
|
||||
+*.scr
|
||||
diff --git a/scripts/Makefile.dtbinst b/scripts/Makefile.dtbinst
|
||||
index 34614a48..8a8313d6 100644
|
||||
index 50d580d77..a08f9bee3 100644
|
||||
--- a/scripts/Makefile.dtbinst
|
||||
+++ b/scripts/Makefile.dtbinst
|
||||
@@ -20,6 +20,9 @@ include scripts/Kbuild.include
|
||||
@@ -13,24 +13,40 @@ src := $(obj)
|
||||
PHONY := __dtbs_install
|
||||
__dtbs_install:
|
||||
|
||||
+export dtbinst_root ?= $(obj)
|
||||
+
|
||||
include include/config/auto.conf
|
||||
include scripts/Kbuild.include
|
||||
include $(src)/Makefile
|
||||
|
||||
dtbinst-files := $(sort $(dtb-y) $(if $(CONFIG_OF_ALL_DTBS), $(dtb-)))
|
||||
|
||||
-dtbs := $(addprefix $(dst)/, $(dtb-y) $(if $(CONFIG_OF_ALL_DTBS),$(dtb-)))
|
||||
-subdirs := $(addprefix $(obj)/, $(subdir-y) $(subdir-m))
|
||||
+dtbinst-files := $(sort $(dtb-y) $(if $(CONFIG_OF_ALL_DTBS), $(dtb-)))
|
||||
+dtboinst-files := $(dtbo-y)
|
||||
+script-files := $(scr-y)
|
||||
+readme-files := $(dtbotxt-y)
|
||||
dtbinst-dirs := $(subdir-y) $(subdir-m)
|
||||
|
||||
# Helper targets for Installing DTBs into the boot directory
|
||||
@@ -32,10 +35,19 @@ install-dir = $(patsubst $(dtbinst-root)%,$(INSTALL_DTBS_PATH)%,$(obj))
|
||||
$(dtbinst-files): %.dtb: $(obj)/%.dtb
|
||||
$(call cmd,dtb_install,$(install-dir))
|
||||
|
||||
+dtbinst-dirs := $(subdir-y) $(subdir-m)
|
||||
+
|
||||
+# Helper targets for Installing DTBs into the boot directory
|
||||
+quiet_cmd_dtb_install = INSTALL $<
|
||||
+ cmd_dtb_install = mkdir -p $(2); cp $< $(2)
|
||||
+
|
||||
+install-dir = $(patsubst $(dtbinst_root)%,$(INSTALL_DTBS_PATH)%,$(obj))
|
||||
+
|
||||
+$(dtbinst-files): %.dtb: $(obj)/%.dtb
|
||||
+ $(call cmd,dtb_install,$(install-dir))
|
||||
+
|
||||
+$(dtboinst-files): %.dtbo: $(obj)/%.dtbo
|
||||
+ $(call cmd,dtb_install,$(install-dir))
|
||||
+
|
||||
|
||||
-__dtbs_install: $(dtbs) $(subdirs)
|
||||
- @:
|
||||
+$(script-files): %.scr: $(obj)/%.scr
|
||||
+ $(call cmd,dtb_install,$(install-dir))
|
||||
+
|
||||
|
||||
-quiet_cmd_dtb_install = INSTALL $@
|
||||
- cmd_dtb_install = install -D $< $@
|
||||
+$(readme-files): %: $(src)/%
|
||||
+ $(call cmd,dtb_install,$(install-dir))
|
||||
+
|
||||
$(dtbinst-dirs):
|
||||
$(Q)$(MAKE) $(dtbinst)=$(obj)/$@
|
||||
|
||||
-PHONY += $(dtbinst-files) $(dtbinst-dirs)
|
||||
-__dtbs_install: $(dtbinst-files) $(dtbinst-dirs)
|
||||
|
||||
-$(dst)/%.dtb: $(obj)/%.dtb
|
||||
- $(call cmd,dtb_install)
|
||||
+$(dtbinst-dirs):
|
||||
+ $(Q)$(MAKE) $(dtbinst)=$(obj)/$@
|
||||
|
||||
-PHONY += $(subdirs)
|
||||
-$(subdirs):
|
||||
- $(Q)$(MAKE) $(dtbinst)=$@ dst=$(patsubst $(obj)/%,$(dst)/%,$@)
|
||||
+PHONY += $(dtbinst-files) $(dtboinst-files) $(script-files) $(readme-files) $(dtbinst-dirs)
|
||||
+__dtbs_install: $(dtbinst-files) $(dtboinst-files) $(script-files) $(readme-files) $(dtbinst-dirs)
|
||||
|
||||
|
||||
.PHONY: $(PHONY)
|
||||
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
|
||||
index 58c05e5d..2b95dda9 100644
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
|
||||
index 9a7def7..08c6a05 100644
|
||||
index 5e4c453..028ef66 100644
|
||||
--- a/drivers/spi/spi.c
|
||||
+++ b/drivers/spi/spi.c
|
||||
@@ -2884,6 +2884,19 @@ int spi_setup(struct spi_device *spi)
|
||||
@@ -3262,6 +3262,19 @@ int spi_setup(struct spi_device *spi)
|
||||
if (spi->controller->setup)
|
||||
status = spi->controller->setup(spi);
|
||||
|
||||
|
@ -19,6 +19,6 @@ index 9a7def7..08c6a05 100644
|
|||
+ }
|
||||
+ }
|
||||
+
|
||||
spi_set_cs(spi, false);
|
||||
|
||||
dev_dbg(&spi->dev, "setup mode %d, %s%s%s%s%u bits/w, %u Hz max --> %d\n",
|
||||
if (spi->controller->auto_runtime_pm && spi->controller->set_cs) {
|
||||
status = pm_runtime_get_sync(spi->controller->dev.parent);
|
||||
if (status < 0) {
|
||||
|
|
|
@ -13,7 +13,7 @@ new file mode 100644
|
|||
index 0000000..39d6a27
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/boot/dts/overlay/Makefile
|
||||
@@ -0,0 +1,89 @@
|
||||
@@ -0,0 +1,97 @@
|
||||
+# SPDX-License-Identifier: GPL-2.0
|
||||
+dtbo-$(CONFIG_MACH_SUN4I) += \
|
||||
+ sun4i-a10-analog-codec.dtbo \
|
||||
|
@ -92,7 +92,15 @@ index 0000000..39d6a27
|
|||
+ sun8i-h3-usbhost1.dtbo \
|
||||
+ sun8i-h3-usbhost2.dtbo \
|
||||
+ sun8i-h3-usbhost3.dtbo \
|
||||
+ sun8i-h3-w1-gpio.dtbo
|
||||
+ sun8i-h3-w1-gpio.dtbo \
|
||||
+ sun8i-r40-i2c2.dtbo \
|
||||
+ sun8i-r40-i2c3.dtbo \
|
||||
+ sun8i-r40-spi-spidev0.dtbo \
|
||||
+ sun8i-r40-spi-spidev1.dtbo \
|
||||
+ sun8i-r40-uart2.dtbo \
|
||||
+ sun8i-r40-uart4.dtbo \
|
||||
+ sun8i-r40-uart5.dtbo \
|
||||
+ sun8i-r40-uart7.dtbo
|
||||
+
|
||||
+scr-$(CONFIG_MACH_SUN4I) += sun4i-a10-fixup.scr
|
||||
+scr-$(CONFIG_MACH_SUN5I) += sun5i-a13-fixup.scr
|
||||
|
@ -4520,6 +4528,236 @@ index 0000000..f4ccb7f
|
|||
+ };
|
||||
+ };
|
||||
+};
|
||||
diff --git a/arch/arm/boot/dts/overlay/sun8i-r40-i2c2.dts b/arch/arm/boot/dts/overlay/sun8i-r40-i2c2.dts
|
||||
new file mode 100644
|
||||
index 0000000..a1e3284
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/boot/dts/overlay/sun8i-r40-i2c2.dts
|
||||
@@ -0,0 +1,20 @@
|
||||
+/dts-v1/;
|
||||
+/plugin/;
|
||||
+
|
||||
+/ {
|
||||
+ compatible = "allwinner,sun8i-h3";
|
||||
+
|
||||
+ fragment@0 {
|
||||
+ target-path = "/aliases";
|
||||
+ __overlay__ {
|
||||
+ i2c2 = "/soc/i2c@1c2b400";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ fragment@1 {
|
||||
+ target = <&i2c2>;
|
||||
+ __overlay__ {
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
diff --git a/arch/arm/boot/dts/overlay/sun8i-r40-i2c3.dts b/arch/arm/boot/dts/overlay/sun8i-r40-i2c3.dts
|
||||
new file mode 100644
|
||||
index 0000000..a1e3284
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/boot/dts/overlay/sun8i-r40-i2c3.dts
|
||||
@@ -0,0 +1,20 @@
|
||||
+/dts-v1/;
|
||||
+/plugin/;
|
||||
+
|
||||
+/ {
|
||||
+ compatible = "allwinner,sun8i-h3";
|
||||
+
|
||||
+ fragment@0 {
|
||||
+ target-path = "/aliases";
|
||||
+ __overlay__ {
|
||||
+ i2c3 = "/soc/i2c@1c2b800";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ fragment@1 {
|
||||
+ target = <&i2c3>;
|
||||
+ __overlay__ {
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
diff --git a/arch/arm/boot/dts/overlay/sun8i-r40-spi-spidev0.dts b/arch/arm/boot/dts/overlay/sun8i-r40-spi-spidev0.dts
|
||||
new file mode 100644
|
||||
index 0000000..734a9a8
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/boot/dts/overlay/sun8i-r40-spi-spidev0.dts
|
||||
@@ -0,0 +1,27 @@
|
||||
+/dts-v1/;
|
||||
+/ {
|
||||
+ compatible = "allwinner,sun8i-r40";
|
||||
+ fragment@0 {
|
||||
+ target-path = "/aliases";
|
||||
+ __overlay__ {
|
||||
+ spi0 = "/soc/spi@1c05000";
|
||||
+ };
|
||||
+ };
|
||||
+ fragment@1 {
|
||||
+ target = <0xffffffff>;
|
||||
+ __overlay__ {
|
||||
+ #address-cells = <0x00000001>;
|
||||
+ #size-cells = <0x00000000>;
|
||||
+ status = "okay";
|
||||
+ spidev@0 {
|
||||
+ compatible = "spidev";
|
||||
+ status = "okay";
|
||||
+ reg = <0x00000000>;
|
||||
+ spi-max-frequency = <0x000f4240>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ __fixups__ {
|
||||
+ spi0 = "/fragment@1:target:0";
|
||||
+ };
|
||||
+};
|
||||
diff --git a/arch/arm/boot/dts/overlay/sun8i-r40-spi-spidev1.dts b/arch/arm/boot/dts/overlay/sun8i-r40-spi-spidev1.dts
|
||||
new file mode 100644
|
||||
index 0000000..d1d637c
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/boot/dts/overlay/sun8i-r40-spi-spidev1.dts
|
||||
@@ -0,0 +1,27 @@
|
||||
+/dts-v1/;
|
||||
+/ {
|
||||
+ compatible = "allwinner,sun8i-r40";
|
||||
+ fragment@0 {
|
||||
+ target-path = "/aliases";
|
||||
+ __overlay__ {
|
||||
+ spi1 = "/soc/spi@1c06000";
|
||||
+ };
|
||||
+ };
|
||||
+ fragment@1 {
|
||||
+ target = <0xffffffff>;
|
||||
+ __overlay__ {
|
||||
+ #address-cells = <0x00000001>;
|
||||
+ #size-cells = <0x00000000>;
|
||||
+ status = "okay";
|
||||
+ spidev@0 {
|
||||
+ compatible = "spidev";
|
||||
+ status = "okay";
|
||||
+ reg = <0x00000000>;
|
||||
+ spi-max-frequency = <0x000f4240>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+ __fixups__ {
|
||||
+ spi1 = "/fragment@1:target:0";
|
||||
+ };
|
||||
+};
|
||||
diff --git a/arch/arm/boot/dts/overlay/sun8i-r40-uart2.dts b/arch/arm/boot/dts/overlay/sun8i-r40-uart2.dts
|
||||
new file mode 100644
|
||||
index 0000000..65e946d
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/boot/dts/overlay/sun8i-r40-uart2.dts
|
||||
@@ -0,0 +1,22 @@
|
||||
+/dts-v1/;
|
||||
+/ {
|
||||
+ compatible = "allwinner,sun8i-r40";
|
||||
+ fragment@0 {
|
||||
+ target-path = "/aliases";
|
||||
+ __overlay__ {
|
||||
+ serial2 = "/soc/serial@1c28800";
|
||||
+ };
|
||||
+ };
|
||||
+ fragment@1 {
|
||||
+ target = <0xffffffff>;
|
||||
+ __overlay__ {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <0xffffffff>;
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+ };
|
||||
+ __fixups__ {
|
||||
+ uart2 = "/fragment@1:target:0";
|
||||
+ uart2_pi_pins = "/fragment@1/__overlay__:pinctrl-0:0";
|
||||
+ };
|
||||
+};
|
||||
diff --git a/arch/arm/boot/dts/overlay/sun8i-r40-uart4.dts b/arch/arm/boot/dts/overlay/sun8i-r40-uart4.dts
|
||||
new file mode 100644
|
||||
index 0000000..65e946d
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/boot/dts/overlay/sun8i-r40-uart4.dts
|
||||
@@ -0,0 +1,22 @@
|
||||
+/dts-v1/;
|
||||
+/ {
|
||||
+ compatible = "allwinner,sun8i-r40";
|
||||
+ fragment@0 {
|
||||
+ target-path = "/aliases";
|
||||
+ __overlay__ {
|
||||
+ serial4 = "/soc/serial@1c29000";
|
||||
+ };
|
||||
+ };
|
||||
+ fragment@1 {
|
||||
+ target = <0xffffffff>;
|
||||
+ __overlay__ {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <0xffffffff>;
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+ };
|
||||
+ __fixups__ {
|
||||
+ uart4 = "/fragment@1:target:0";
|
||||
+ uart4_ph_pins = "/fragment@1/__overlay__:pinctrl-0:0";
|
||||
+ };
|
||||
+};
|
||||
diff --git a/arch/arm/boot/dts/overlay/sun8i-r40-uart5.dts b/arch/arm/boot/dts/overlay/sun8i-r40-uart5.dts
|
||||
new file mode 100644
|
||||
index 0000000..65e946d
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/boot/dts/overlay/sun8i-r40-uart5.dts
|
||||
@@ -0,0 +1,22 @@
|
||||
+/dts-v1/;
|
||||
+/ {
|
||||
+ compatible = "allwinner,sun8i-r40";
|
||||
+ fragment@0 {
|
||||
+ target-path = "/aliases";
|
||||
+ __overlay__ {
|
||||
+ serial5 = "/soc/serial@1c29400";
|
||||
+ };
|
||||
+ };
|
||||
+ fragment@1 {
|
||||
+ target = <0xffffffff>;
|
||||
+ __overlay__ {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <0xffffffff>;
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+ };
|
||||
+ __fixups__ {
|
||||
+ uart5 = "/fragment@1:target:0";
|
||||
+ uart5_ph_pins = "/fragment@1/__overlay__:pinctrl-0:0";
|
||||
+ };
|
||||
+};
|
||||
diff --git a/arch/arm/boot/dts/overlay/sun8i-r40-uart7.dts b/arch/arm/boot/dts/overlay/sun8i-r40-uart7.dts
|
||||
new file mode 100644
|
||||
index 0000000..65e946d
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/boot/dts/overlay/sun8i-r40-uart7.dts
|
||||
@@ -0,0 +1,22 @@
|
||||
+/dts-v1/;
|
||||
+/ {
|
||||
+ compatible = "allwinner,sun8i-r40";
|
||||
+ fragment@0 {
|
||||
+ target-path = "/aliases";
|
||||
+ __overlay__ {
|
||||
+ serial7 = "/soc/serial@1c29c00";
|
||||
+ };
|
||||
+ };
|
||||
+ fragment@1 {
|
||||
+ target = <0xffffffff>;
|
||||
+ __overlay__ {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <0xffffffff>;
|
||||
+ status = "okay";
|
||||
+ };
|
||||
+ };
|
||||
+ __fixups__ {
|
||||
+ uart7 = "/fragment@1:target:0";
|
||||
+ uart7_pi_pins = "/fragment@1/__overlay__:pinctrl-0:0";
|
||||
+ };
|
||||
+};
|
||||
diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
|
||||
index fa35163..89df4ff 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/Makefile
|
||||
|
|
|
@ -2,7 +2,7 @@ diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts b/arch/arm6
|
|||
index ec0296a85..ad2c64d51 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts
|
||||
@@ -293,3 +293,36 @@ &uart0 {
|
||||
@@ -293,3 +293,32 @@ &uart0 {
|
||||
&usbphy {
|
||||
status = "okay";
|
||||
};
|
||||
|
@ -11,7 +11,7 @@ index ec0296a85..ad2c64d51 100644
|
|||
+status = "okay";
|
||||
+};
|
||||
+
|
||||
+&sound_hdmi {
|
||||
+&hdmi_sound {
|
||||
+status = "okay";
|
||||
+};
|
||||
+
|
||||
|
@ -20,10 +20,6 @@ index ec0296a85..ad2c64d51 100644
|
|||
+status = "okay";
|
||||
+};
|
||||
+
|
||||
+&i2s1 {
|
||||
+status = "okay";
|
||||
+};
|
||||
+
|
||||
+&i2s2 {
|
||||
+status = "okay";
|
||||
+};
|
||||
|
|
12
patch/kernel/sunxi-current/ruart-alias.patch
Normal file
12
patch/kernel/sunxi-current/ruart-alias.patch
Normal file
|
@ -0,0 +1,12 @@
|
|||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts
|
||||
index afee79f..7a8f8c6 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts
|
||||
@@ -16,6 +16,7 @@
|
||||
aliases {
|
||||
serial0 = &uart0;
|
||||
serial1 = &uart1;
|
||||
+ serial9 = &r_uart;
|
||||
ethernet0 = &emac;
|
||||
};
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
--- a/sound/soc/codecs/Kconfig 2020-02-13 23:44:47.394937509 +0100
|
||||
+++ b/sound/soc/codecs/Kconfig 2020-02-13 23:47:11.571103180 +0100
|
||||
@@ -880,7 +880,7 @@
|
||||
@@ -917,7 +917,7 @@
|
||||
select REGMAP_SPI
|
||||
|
||||
config SND_SOC_PCM5102A
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
---
|
||||
drivers/gpu/drm/panfrost/panfrost_devfreq.c | 16 ++++++++++++----
|
||||
1 file changed, 12 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
|
||||
index 413987038fbf..62541f4edd81 100644
|
||||
--- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c
|
||||
+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
|
||||
@@ -90,8 +90,11 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
|
||||
cur_freq = clk_get_rate(pfdev->clock);
|
||||
|
||||
opp = devfreq_recommended_opp(dev, &cur_freq, 0);
|
||||
- if (IS_ERR(opp))
|
||||
- return PTR_ERR(opp);
|
||||
+ if (IS_ERR(opp)) {
|
||||
+ DRM_DEV_ERROR(dev, "Failed to set recommended OPP\n");
|
||||
+ ret = PTR_ERR(opp);
|
||||
+ goto err_opp;
|
||||
+ }
|
||||
|
||||
panfrost_devfreq_profile.initial_freq = cur_freq;
|
||||
dev_pm_opp_put(opp);
|
||||
@@ -100,8 +103,8 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
|
||||
DEVFREQ_GOV_SIMPLE_ONDEMAND, NULL);
|
||||
if (IS_ERR(devfreq)) {
|
||||
DRM_DEV_ERROR(dev, "Couldn't initialize GPU devfreq\n");
|
||||
- dev_pm_opp_of_remove_table(dev);
|
||||
- return PTR_ERR(devfreq);
|
||||
+ ret = PTR_ERR(devfreq);
|
||||
+ goto err_opp;
|
||||
}
|
||||
pfdev->devfreq.devfreq = devfreq;
|
||||
|
||||
@@ -112,6 +115,11 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
|
||||
pfdev->devfreq.cooling = cooling;
|
||||
|
||||
return 0;
|
||||
+
|
||||
+err_opp:
|
||||
+ dev_pm_opp_of_remove_table(dev);
|
||||
+
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
void panfrost_devfreq_fini(struct panfrost_device *pfdev)
|
||||
--
|
||||
2.20.1
|
|
@ -0,0 +1,81 @@
|
|||
---
|
||||
drivers/gpu/drm/panfrost/panfrost_devfreq.c | 34 ++++++++++++++++++---
|
||||
drivers/gpu/drm/panfrost/panfrost_device.h | 1 +
|
||||
2 files changed, 31 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
|
||||
index 62541f4edd81..2dc8e2355358 100644
|
||||
--- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c
|
||||
+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
|
||||
@@ -78,12 +78,26 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
|
||||
struct device *dev = &pfdev->pdev->dev;
|
||||
struct devfreq *devfreq;
|
||||
struct thermal_cooling_device *cooling;
|
||||
+ const char *mali = "mali";
|
||||
+ struct opp_table *opp_table = NULL;
|
||||
+
|
||||
+ /* Regulator is optional */
|
||||
+ opp_table = dev_pm_opp_set_regulators(dev, &mali, 1);
|
||||
+ if (IS_ERR(opp_table)) {
|
||||
+ ret = PTR_ERR(opp_table);
|
||||
+ if (ret != -ENODEV) {
|
||||
+ DRM_DEV_ERROR(dev, "Failed to set regulator: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+ pfdev->devfreq.opp_table = opp_table;
|
||||
|
||||
ret = dev_pm_opp_of_add_table(dev);
|
||||
- if (ret == -ENODEV) /* Optional, continue without devfreq */
|
||||
- return 0;
|
||||
- else if (ret)
|
||||
- return ret;
|
||||
+ if (ret) {
|
||||
+ if (ret == -ENODEV) /* Optional, continue without devfreq */
|
||||
+ ret = 0;
|
||||
+ goto err_opp_reg;
|
||||
+ }
|
||||
|
||||
panfrost_devfreq_reset(pfdev);
|
||||
|
||||
@@ -119,6 +133,12 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
|
||||
err_opp:
|
||||
dev_pm_opp_of_remove_table(dev);
|
||||
|
||||
+err_opp_reg:
|
||||
+ if (pfdev->devfreq.opp_table) {
|
||||
+ dev_pm_opp_put_regulators(pfdev->devfreq.opp_table);
|
||||
+ pfdev->devfreq.opp_table = NULL;
|
||||
+ }
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -126,7 +146,13 @@ void panfrost_devfreq_fini(struct panfrost_device *pfdev)
|
||||
{
|
||||
if (pfdev->devfreq.cooling)
|
||||
devfreq_cooling_unregister(pfdev->devfreq.cooling);
|
||||
+
|
||||
dev_pm_opp_of_remove_table(&pfdev->pdev->dev);
|
||||
+
|
||||
+ if (pfdev->devfreq.opp_table) {
|
||||
+ dev_pm_opp_put_regulators(pfdev->devfreq.opp_table);
|
||||
+ pfdev->devfreq.opp_table = NULL;
|
||||
+ }
|
||||
}
|
||||
|
||||
void panfrost_devfreq_resume(struct panfrost_device *pfdev)
|
||||
diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h b/drivers/gpu/drm/panfrost/panfrost_device.h
|
||||
index 06713811b92c..f6b0c779dfe5 100644
|
||||
--- a/drivers/gpu/drm/panfrost/panfrost_device.h
|
||||
+++ b/drivers/gpu/drm/panfrost/panfrost_device.h
|
||||
@@ -86,6 +86,7 @@ struct panfrost_device {
|
||||
struct {
|
||||
struct devfreq *devfreq;
|
||||
struct thermal_cooling_device *cooling;
|
||||
+ struct opp_table *opp_table;
|
||||
ktime_t busy_time;
|
||||
ktime_t idle_time;
|
||||
ktime_t time_last_update;
|
||||
--
|
||||
2.20.1
|
|
@ -1,11 +1,44 @@
|
|||
diff --git a/include/linux/timekeeping32.h b/include/linux/timekeeping32.h
|
||||
index cc59cc9..a0f5143 100644
|
||||
index 266017f..4444cec 100644
|
||||
--- a/include/linux/timekeeping32.h
|
||||
+++ b/include/linux/timekeeping32.h
|
||||
@@ -43,4 +43,15 @@ static inline void getboottime(struct timespec *ts)
|
||||
*ts = timespec64_to_timespec(ts64);
|
||||
@@ -11,4 +11,48 @@ static inline unsigned long get_seconds(void)
|
||||
return ktime_get_real_seconds();
|
||||
}
|
||||
|
||||
+/* Map the ktime_t to timespec conversion to ns_to_timespec function */
|
||||
+#define ktime_to_timespec(kt) ns_to_timespec((kt))
|
||||
+#define timespec old_timespec32
|
||||
+
|
||||
+static inline struct timespec ns_to_timespec(const s64 nsec)
|
||||
+{
|
||||
+ struct timespec ts;
|
||||
+ s32 rem;
|
||||
+ if (!nsec)
|
||||
+ return (struct timespec) {0, 0};
|
||||
+ ts.tv_sec = div_s64_rem(nsec, NSEC_PER_SEC, &rem);
|
||||
+ if (unlikely(rem < 0)) {
|
||||
+ ts.tv_sec--;
|
||||
+ rem += NSEC_PER_SEC;
|
||||
+ }
|
||||
+ ts.tv_nsec = rem;
|
||||
+ return ts;
|
||||
+}
|
||||
+
|
||||
+/* timespec64 is defined as timespec here */
|
||||
+static inline struct timespec timespec64_to_timespec(const struct timespec64 ts64)
|
||||
+{
|
||||
+ return *(const struct timespec *)&ts64;
|
||||
+}
|
||||
+
|
||||
+static inline void getboottime(struct timespec *ts)
|
||||
+{
|
||||
+ struct timespec64 ts64;
|
||||
+
|
||||
+ getboottime64(&ts64);
|
||||
+ *ts = timespec64_to_timespec(ts64);
|
||||
+}
|
||||
+
|
||||
+static inline void get_monotonic_boottime(struct timespec *ts)
|
||||
+{
|
||||
+ *ts = ktime_to_timespec(ktime_get_boottime());
|
||||
|
|
|
@ -89,11 +89,11 @@ index f4af3fdcc..3b1f50791 100644
|
|||
};
|
||||
};
|
||||
diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi
|
||||
index ae3f37720..74e6b3b82 100644
|
||||
index a79956f7b..b4891d31f 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-h3.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun8i-h3.dtsi
|
||||
@@ -89,15 +89,6 @@
|
||||
};
|
||||
@@ -98,15 +98,6 @@
|
||||
interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
|
||||
};
|
||||
|
||||
- thermal-zones {
|
||||
|
@ -105,10 +105,10 @@ index ae3f37720..74e6b3b82 100644
|
|||
- };
|
||||
- };
|
||||
-
|
||||
pmu {
|
||||
compatible = "arm,cortex-a7-pmu";
|
||||
interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
|
||||
@@ -188,32 +179,74 @@
|
||||
timer {
|
||||
compatible = "arm,armv7-timer";
|
||||
interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
|
||||
@@ -210,32 +201,74 @@
|
||||
};
|
||||
|
||||
thermal-zones {
|
||||
|
@ -120,17 +120,16 @@ index ae3f37720..74e6b3b82 100644
|
|||
+ /* milliseconds */
|
||||
+ polling-delay-passive = <250>;
|
||||
+ polling-delay = <1000>;
|
||||
+ thermal-sensors = <&ths>;
|
||||
+
|
||||
+ trips {
|
||||
+ thermal-sensors = <&ths>;
|
||||
|
||||
trips {
|
||||
- cpu_hot_trip: cpu-hot {
|
||||
+ cpu_warm: cpu_warm {
|
||||
+ temperature = <75000>;
|
||||
+ hysteresis = <2000>;
|
||||
+ type = "passive";
|
||||
+ };
|
||||
|
||||
- trips {
|
||||
- cpu_hot_trip: cpu-hot {
|
||||
+
|
||||
+ cpu_hot_pre: cpu_hot_pre {
|
||||
temperature = <80000>;
|
||||
hysteresis = <2000>;
|
||||
|
@ -165,14 +164,13 @@ index ae3f37720..74e6b3b82 100644
|
|||
};
|
||||
};
|
||||
|
||||
- cooling-maps {
|
||||
cooling-maps {
|
||||
- cpu-hot-limit {
|
||||
- trip = <&cpu_hot_trip>;
|
||||
- cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
|
||||
- <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
|
||||
- <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
|
||||
- <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
|
||||
+ cooling-maps {
|
||||
+ cpu_warm_limit_cpu {
|
||||
+ trip = <&cpu_warm>;
|
||||
+ cooling-device = <&cpu0 THERMAL_NO_LIMIT 2>;
|
||||
|
|
|
@ -134,11 +134,12 @@ diff --git a/include/media/dvb-usb-ids.h b/include/media/dvb-usb-ids.h
|
|||
index f9e73b4..d606248 100644
|
||||
--- a/include/media/dvb-usb-ids.h
|
||||
+++ b/include/media/dvb-usb-ids.h
|
||||
@@ -387,6 +387,7 @@
|
||||
@@ -387,7 +387,8 @@
|
||||
#define USB_PID_MYGICA_D689 0xd811
|
||||
#define USB_PID_MYGICA_T230 0xc688
|
||||
#define USB_PID_MYGICA_T230C 0xc689
|
||||
+#define USB_PID_MYGICA_T230C_V2 0xc68a
|
||||
#define USB_PID_MYGICA_T230C2 0xc68a
|
||||
+#define USB_PID_MYGICA_T230C_V2 0xc68a
|
||||
#define USB_PID_ELGATO_EYETV_DIVERSITY 0x0011
|
||||
#define USB_PID_ELGATO_EYETV_DTT 0x0021
|
||||
#define USB_PID_ELGATO_EYETV_DTT_2 0x003f
|
|
@ -340458,10 +340458,10 @@ index 00000000..7c349e79
|
|||
+
|
||||
diff --git a/drivers/net/wireless/realtek/rtl8723cs/os_dep/linux/rtw_proc.c b/drivers/net/wireless/realtek/rtl8723cs/os_dep/linux/rtw_proc.c
|
||||
new file mode 100644
|
||||
index 00000000..cee446fa
|
||||
index 0000000..77d6e90
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/wireless/realtek/rtl8723cs/os_dep/linux/rtw_proc.c
|
||||
@@ -0,0 +1,2038 @@
|
||||
@@ -0,0 +1,2072 @@
|
||||
+/******************************************************************************
|
||||
+ *
|
||||
+ * Copyright(c) 2007 - 2013 Realtek Corporation. All rights reserved.
|
||||
|
@ -340532,8 +340532,15 @@ index 00000000..cee446fa
|
|||
+ return entry;
|
||||
+}
|
||||
+
|
||||
+inline struct proc_dir_entry *rtw_proc_create_entry(const char *name, struct proc_dir_entry *parent,
|
||||
+ const struct file_operations *fops, void * data)
|
||||
+inline struct proc_dir_entry *rtw_proc_create_entry(const char *name, struct proc_dir_entry *parent,
|
||||
+#if 1 //(LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0))
|
||||
+ #pragma message "Greater or equal 5.6.0"
|
||||
+ const struct proc_ops *fops,
|
||||
+#else
|
||||
+ #pragma message "Lower than 5.6.0 : " LINUX_VERSION_CODE
|
||||
+ const struct file_operations *fops,
|
||||
+#endif
|
||||
+ void * data)
|
||||
+{
|
||||
+ struct proc_dir_entry *entry;
|
||||
+
|
||||
|
@ -340598,13 +340605,13 @@ index 00000000..cee446fa
|
|||
+ } else {
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+#ifdef DBG_MEM_ALLOC
|
||||
+static int proc_get_mstat(struct seq_file *m, void *v)
|
||||
+{
|
||||
+{
|
||||
+ rtw_mstat_dump(m);
|
||||
+ return 0;
|
||||
+}
|
||||
|
@ -340652,13 +340659,22 @@ index 00000000..cee446fa
|
|||
+ ssize_t index = (ssize_t)PDE_DATA(file_inode(file));
|
||||
+ const struct rtw_proc_hdl *hdl = drv_proc_hdls+index;
|
||||
+ ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *, void *) = hdl->write;
|
||||
+
|
||||
+
|
||||
+ if (write)
|
||||
+ return write(file, buffer, count, pos, NULL);
|
||||
+
|
||||
+ return -EROFS;
|
||||
+}
|
||||
+
|
||||
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0))
|
||||
+static const struct proc_ops rtw_drv_proc_fops = {
|
||||
+ .proc_open = rtw_drv_proc_open,
|
||||
+ .proc_read = seq_read,
|
||||
+ .proc_lseek = seq_lseek,
|
||||
+ .proc_release = single_release,
|
||||
+ .proc_write = rtw_drv_proc_write,
|
||||
+};
|
||||
+#else
|
||||
+static const struct file_operations rtw_drv_proc_fops = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .open = rtw_drv_proc_open,
|
||||
|
@ -340667,6 +340683,7 @@ index 00000000..cee446fa
|
|||
+ .release = single_release,
|
||||
+ .write = rtw_drv_proc_write,
|
||||
+};
|
||||
+#endif
|
||||
+
|
||||
+int rtw_drv_proc_init(void)
|
||||
+{
|
||||
|
@ -340782,9 +340799,9 @@ index 00000000..cee446fa
|
|||
+{
|
||||
+ struct net_device *dev = data;
|
||||
+ _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
|
||||
+ char tmp[32]={0};
|
||||
+ char tmp[32]={0};
|
||||
+ int num=0,gpio_pin=0,gpio_mode=0;//gpio_mode:0 input 1:output;
|
||||
+
|
||||
+
|
||||
+ if (count < 2)
|
||||
+ return -EFAULT;
|
||||
+
|
||||
|
@ -340796,21 +340813,20 @@ index 00000000..cee446fa
|
|||
+ if (buffer && !copy_from_user(tmp, buffer, count)) {
|
||||
+ num =sscanf(tmp, "%d %d",&gpio_pin,&gpio_mode);
|
||||
+ DBG_871X("num=%d gpio_pin=%d mode=%d\n",num,gpio_pin,gpio_mode);
|
||||
+ padapter->pre_gpio_pin=gpio_pin;
|
||||
+
|
||||
+ padapter->pre_gpio_pin=gpio_pin;
|
||||
+ if(gpio_mode==0 || gpio_mode==1 )
|
||||
+ rtw_hal_config_gpio(padapter, gpio_pin,gpio_mode);
|
||||
+ rtw_hal_config_gpio(padapter, gpio_pin,gpio_mode);
|
||||
+ }
|
||||
+ return count;
|
||||
+
|
||||
+}
|
||||
+
|
||||
+static ssize_t proc_set_gpio_output_value(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data)
|
||||
+{
|
||||
+ struct net_device *dev = data;
|
||||
+ _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
|
||||
+ char tmp[32]={0};
|
||||
+ char tmp[32]={0};
|
||||
+ int num=0,gpio_pin=0,pin_mode=0;//pin_mode: 1 high 0:low
|
||||
+
|
||||
+
|
||||
+ if (count < 2)
|
||||
+ return -EFAULT;
|
||||
+
|
||||
|
@ -340823,33 +340839,33 @@ index 00000000..cee446fa
|
|||
+ num =sscanf(tmp, "%d %d",&gpio_pin,&pin_mode);
|
||||
+ DBG_871X("num=%d gpio_pin=%d pin_high=%d\n",num,gpio_pin,pin_mode);
|
||||
+ padapter->pre_gpio_pin=gpio_pin;
|
||||
+
|
||||
+ if(pin_mode==0 || pin_mode==1 )
|
||||
+ rtw_hal_set_gpio_output_value(padapter, gpio_pin,pin_mode);
|
||||
+ rtw_hal_set_gpio_output_value(padapter, gpio_pin,pin_mode);
|
||||
+ }
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+static int proc_get_gpio(struct seq_file *m, void *v)
|
||||
+{
|
||||
+ u8 gpioreturnvalue=0;
|
||||
+ struct net_device *dev = m->private;
|
||||
+
|
||||
+
|
||||
+ _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
|
||||
+ if(!padapter)
|
||||
+ if(!padapter)
|
||||
+ return -EFAULT;
|
||||
+ gpioreturnvalue = rtw_hal_get_gpio(padapter, padapter->pre_gpio_pin);
|
||||
+ DBG_871X_SEL_NL(m, "get_gpio %d:%d \n",padapter->pre_gpio_pin ,gpioreturnvalue);
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static ssize_t proc_set_gpio(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data)
|
||||
+{
|
||||
+ struct net_device *dev = data;
|
||||
+ _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
|
||||
+ char tmp[32]={0};
|
||||
+ char tmp[32]={0};
|
||||
+ int num=0,gpio_pin=0;
|
||||
+
|
||||
+
|
||||
+ if (count < 1)
|
||||
+ return -EFAULT;
|
||||
+
|
||||
|
@ -340862,10 +340878,10 @@ index 00000000..cee446fa
|
|||
+ num =sscanf(tmp, "%d",&gpio_pin);
|
||||
+ DBG_871X("num=%d gpio_pin=%d\n",num,gpio_pin);
|
||||
+ padapter->pre_gpio_pin=gpio_pin;
|
||||
+
|
||||
+ }
|
||||
+ return count;
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
+
|
||||
|
@ -340873,9 +340889,8 @@ index 00000000..cee446fa
|
|||
+{
|
||||
+ struct net_device *dev = m->private;
|
||||
+ _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
|
||||
+ if(padapter)
|
||||
+ if(padapter)
|
||||
+ DBG_871X_SEL_NL(m, "linked_info_dump :%s \n", (padapter->bLinkInfoDump)?"enable":"disable");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
|
@ -340884,9 +340899,9 @@ index 00000000..cee446fa
|
|||
+ struct net_device *dev = data;
|
||||
+ _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
|
||||
+
|
||||
+ char tmp[32]={0};
|
||||
+ char tmp[32]={0};
|
||||
+ int mode=0,pre_mode=0;
|
||||
+ int num=0;
|
||||
+ int num=0;
|
||||
+
|
||||
+ if (count < 1)
|
||||
+ return -EFAULT;
|
||||
|
@ -340907,18 +340922,17 @@ index 00000000..cee446fa
|
|||
+ if(num!=1)
|
||||
+ {
|
||||
+ DBG_871X("argument number is wrong\n");
|
||||
+ return -EFAULT;
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ if(mode==1 || (mode==0 && pre_mode==1) ) //not consider pwr_saving 0:
|
||||
+ {
|
||||
+ padapter->bLinkInfoDump = mode;
|
||||
+
|
||||
+ padapter->bLinkInfoDump = mode;
|
||||
+ }
|
||||
+ else if( (mode==2 ) || (mode==0 && pre_mode==2))//consider power_saving
|
||||
+ {
|
||||
+ {
|
||||
+ //DBG_871X("linked_info_dump =%s \n", (padapter->bLinkInfoDump)?"enable":"disable")
|
||||
+ linked_info_dump(padapter,mode);
|
||||
+ linked_info_dump(padapter,mode);
|
||||
+ }
|
||||
+ }
|
||||
+ return count;
|
||||
|
@ -340939,7 +340953,7 @@ index 00000000..cee446fa
|
|||
+ struct net_device *dev = m->private;
|
||||
+ _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
|
||||
+ struct registry_priv *pregpriv = &padapter->registrypriv;
|
||||
+
|
||||
+
|
||||
+ DBG_871X_SEL_NL(m,"wifi_spec=%d\n",pregpriv->wifi_spec);
|
||||
+ return 0;
|
||||
+}
|
||||
|
@ -340968,7 +340982,7 @@ index 00000000..cee446fa
|
|||
+ {
|
||||
+ DBG_871X("argument size is less than 1\n");
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (count > sizeof(tmp)) {
|
||||
+ rtw_warn_on(1);
|
||||
|
@ -341066,7 +341080,7 @@ index 00000000..cee446fa
|
|||
+ _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
|
||||
+ struct recv_priv *precvpriv = &(padapter->recvpriv);
|
||||
+
|
||||
+ DBG_871X_SEL_NL(m,"%d\n",precvpriv->sink_udpport);
|
||||
+ DBG_871X_SEL_NL(m,"%d\n",precvpriv->sink_udpport);
|
||||
+ return 0;
|
||||
+}
|
||||
+static ssize_t proc_set_udpport(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data)
|
||||
|
@ -341074,10 +341088,10 @@ index 00000000..cee446fa
|
|||
+ struct net_device *dev = data;
|
||||
+ _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
|
||||
+ struct recv_priv *precvpriv = &(padapter->recvpriv);
|
||||
+ int sink_udpport = 0;
|
||||
+ int sink_udpport = 0;
|
||||
+ char tmp[32];
|
||||
+
|
||||
+
|
||||
+
|
||||
+
|
||||
+ if (!padapter)
|
||||
+ return -EFAULT;
|
||||
+
|
||||
|
@ -341085,7 +341099,7 @@ index 00000000..cee446fa
|
|||
+ {
|
||||
+ DBG_871X("argument size is less than 1\n");
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (count > sizeof(tmp)) {
|
||||
+ rtw_warn_on(1);
|
||||
|
@ -341103,7 +341117,7 @@ index 00000000..cee446fa
|
|||
+
|
||||
+ }
|
||||
+ precvpriv->sink_udpport = sink_udpport;
|
||||
+
|
||||
+
|
||||
+ return count;
|
||||
+
|
||||
+}
|
||||
|
@ -341559,7 +341573,7 @@ index 00000000..cee446fa
|
|||
+ int num = 0;
|
||||
+
|
||||
+ _rtw_memset(btinfo, 0, 8);
|
||||
+
|
||||
+
|
||||
+ num = sscanf(tmp, "%hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx"
|
||||
+ , &btinfo[0], &btinfo[1], &btinfo[2], &btinfo[3]
|
||||
+ , &btinfo[4], &btinfo[5], &btinfo[6], &btinfo[7]);
|
||||
|
@ -341571,7 +341585,7 @@ index 00000000..cee446fa
|
|||
+
|
||||
+ rtw_btinfo_cmd(padapter, btinfo, btinfo[1]+2);
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
|
@ -341853,7 +341867,7 @@ index 00000000..cee446fa
|
|||
+ if (buffer && !copy_from_user(tmp, buffer, count)) {
|
||||
+
|
||||
+ int num = sscanf(tmp, "%hhu", &acs_satae);
|
||||
+
|
||||
+
|
||||
+ if (num < 1)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
|
@ -341891,7 +341905,7 @@ index 00000000..cee446fa
|
|||
+ {"ht_option", proc_get_ht_option, NULL},
|
||||
+ {"rf_info", proc_get_rf_info, NULL},
|
||||
+ {"scan_param", proc_get_scan_param, proc_set_scan_param},
|
||||
+ {"scan_abort", proc_get_scan_abort, NULL},
|
||||
+ {"scan_abort", proc_get_scan_abort, NULL},
|
||||
+#ifdef CONFIG_SCAN_BACKOP
|
||||
+ {"backop_flags_sta", proc_get_backop_flags_sta, proc_set_backop_flags_sta},
|
||||
+ {"backop_flags_ap", proc_get_backop_flags_ap, proc_set_backop_flags_ap},
|
||||
|
@ -341925,7 +341939,7 @@ index 00000000..cee446fa
|
|||
+ {"mac_reg_dump", proc_get_mac_reg_dump, NULL},
|
||||
+ {"bb_reg_dump", proc_get_bb_reg_dump, NULL},
|
||||
+ {"rf_reg_dump", proc_get_rf_reg_dump, NULL},
|
||||
+
|
||||
+
|
||||
+#ifdef CONFIG_AP_MODE
|
||||
+ {"all_sta_info", proc_get_all_sta_info, NULL},
|
||||
+#endif /* CONFIG_AP_MODE */
|
||||
|
@ -341949,7 +341963,7 @@ index 00000000..cee446fa
|
|||
+ {"rx_ampdu", proc_get_rx_ampdu, proc_set_rx_ampdu},
|
||||
+ {"rx_ampdu_factor",proc_get_rx_ampdu_factor,proc_set_rx_ampdu_factor},
|
||||
+ {"rx_ampdu_density",proc_get_rx_ampdu_density,proc_set_rx_ampdu_density},
|
||||
+ {"tx_ampdu_density",proc_get_tx_ampdu_density,proc_set_tx_ampdu_density},
|
||||
+ {"tx_ampdu_density",proc_get_tx_ampdu_density,proc_set_tx_ampdu_density},
|
||||
+#endif /* CONFIG_80211N_HT */
|
||||
+
|
||||
+ {"en_fwps", proc_get_en_fwps, proc_set_en_fwps},
|
||||
|
@ -342004,7 +342018,7 @@ index 00000000..cee446fa
|
|||
+ {"sink_udpport",proc_get_udpport,proc_set_udpport},
|
||||
+#ifdef DBG_RX_COUNTER_DUMP
|
||||
+ {"dump_rx_cnt_mode",proc_get_rx_cnt_dump,proc_set_rx_cnt_dump},
|
||||
+#endif
|
||||
+#endif
|
||||
+ {"change_bss_chbw", NULL, proc_set_change_bss_chbw},
|
||||
+ {"target_tx_power", proc_get_target_tx_power, NULL},
|
||||
+ {"tx_power_by_rate", proc_get_tx_power_by_rate, NULL},
|
||||
|
@ -342061,6 +342075,15 @@ index 00000000..cee446fa
|
|||
+ return -EROFS;
|
||||
+}
|
||||
+
|
||||
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0))
|
||||
+static const struct proc_ops rtw_adapter_proc_fops = {
|
||||
+ .proc_open = rtw_adapter_proc_open,
|
||||
+ .proc_read = seq_read,
|
||||
+ .proc_lseek = seq_lseek,
|
||||
+ .proc_release = single_release,
|
||||
+ .proc_write = rtw_adapter_proc_write,
|
||||
+};
|
||||
+#else
|
||||
+static const struct file_operations rtw_adapter_proc_fops = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .open = rtw_adapter_proc_open,
|
||||
|
@ -342069,6 +342092,7 @@ index 00000000..cee446fa
|
|||
+ .release = single_release,
|
||||
+ .write = rtw_adapter_proc_write,
|
||||
+};
|
||||
+#endif
|
||||
+
|
||||
+int proc_get_odm_dbg_comp(struct seq_file *m, void *v)
|
||||
+{
|
||||
|
@ -342225,7 +342249,7 @@ index 00000000..cee446fa
|
|||
+
|
||||
+ rtw_odm_adaptivity_parm_set(padapter, (s8)TH_L2H_ini, TH_EDCCA_HL_diff, (s8)TH_L2H_ini_mode2, TH_EDCCA_HL_diff_mode2, EDCCA_enable);
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
|
@ -342328,13 +342352,22 @@ index 00000000..cee446fa
|
|||
+ ssize_t index = (ssize_t)PDE_DATA(file_inode(file));
|
||||
+ const struct rtw_proc_hdl *hdl = odm_proc_hdls+index;
|
||||
+ ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *, void *) = hdl->write;
|
||||
+
|
||||
+
|
||||
+ if (write)
|
||||
+ return write(file, buffer, count, pos, ((struct seq_file *)file->private_data)->private);
|
||||
+
|
||||
+ return -EROFS;
|
||||
+}
|
||||
+
|
||||
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0))
|
||||
+static const struct proc_ops rtw_odm_proc_fops = {
|
||||
+ .proc_open = rtw_odm_proc_open,
|
||||
+ .proc_read = seq_read,
|
||||
+ .proc_lseek = seq_lseek,
|
||||
+ .proc_release = single_release,
|
||||
+ .proc_write = rtw_odm_proc_write,
|
||||
+};
|
||||
+#else
|
||||
+static const struct file_operations rtw_odm_proc_fops = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .open = rtw_odm_proc_open,
|
||||
|
@ -342343,6 +342376,7 @@ index 00000000..cee446fa
|
|||
+ .release = single_release,
|
||||
+ .write = rtw_odm_proc_write,
|
||||
+};
|
||||
+#endif
|
||||
+
|
||||
+struct proc_dir_entry *rtw_odm_proc_init(struct net_device *dev)
|
||||
+{
|
||||
|
|
|
@ -30,6 +30,6 @@ index 9051a1097258..0b702168981c 100644
|
|||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&sound_hdmi {
|
||||
+&hdmi_sound {
|
||||
+ status = "okay";
|
||||
+};
|
||||
|
|
|
@ -16,7 +16,7 @@ new file mode 100644
|
|||
index 000000000..731c705a4
|
||||
--- /dev/null
|
||||
+++ b/arch/arm/boot/dts/sun8i-h3-nanopi-r1.dts
|
||||
@@ -0,0 +1,190 @@
|
||||
@@ -0,0 +1,170 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2019 Igor Pecovnik <igor@armbian.com>
|
||||
+ *
|
||||
|
@ -88,22 +88,6 @@ index 000000000..731c705a4
|
|||
+ gpio = <&pio 3 6 GPIO_ACTIVE_HIGH>;
|
||||
+ };
|
||||
+
|
||||
+ vdd_cpux: gpio-regulator {
|
||||
+ compatible = "regulator-gpio";
|
||||
+ pinctrl-names = "default";
|
||||
+ regulator-name = "vdd-cpux";
|
||||
+ regulator-type = "voltage";
|
||||
+ regulator-boot-on;
|
||||
+ regulator-always-on;
|
||||
+ regulator-min-microvolt = <1100000>;
|
||||
+ regulator-max-microvolt = <1300000>;
|
||||
+ regulator-ramp-delay = <50>; /* 4ms */
|
||||
+ gpios = <&r_pio 0 6 GPIO_ACTIVE_HIGH>; /* PL6 */
|
||||
+ gpios-states = <0x1>;
|
||||
+ states = <1100000 0x0
|
||||
+ 1300000 0x1>;
|
||||
+ };
|
||||
+
|
||||
+ leds {
|
||||
+ /delete-node/ status;
|
||||
+ /delete-node/ pwr;
|
||||
|
@ -143,10 +127,6 @@ index 000000000..731c705a4
|
|||
+ };
|
||||
+};
|
||||
+
|
||||
+&cpu0 {
|
||||
+ cpu-supply = <&vdd_cpux>;
|
||||
+};
|
||||
+
|
||||
+&emac {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&emac_rgmii_pins>;
|
||||
|
|
|
@ -77,7 +77,7 @@ index 3792566cd..42b838b1f 100644
|
|||
+ "MIC2", "Internal Microphone Right";
|
||||
+};
|
||||
+
|
||||
+&sound_hdmi {
|
||||
+&hdmi_sound {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
|
|
155
patch/kernel/sunxi-current/xxx-teres-fixed.patch.disabled
Normal file
155
patch/kernel/sunxi-current/xxx-teres-fixed.patch.disabled
Normal file
|
@ -0,0 +1,155 @@
|
|||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts
|
||||
index 1069e70..8fbdab7 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts
|
||||
@@ -19,6 +19,15 @@
|
||||
|
||||
aliases {
|
||||
serial0 = &uart0;
|
||||
+ ethernet0 = &rtl8723bs;
|
||||
+ };
|
||||
+
|
||||
+ backlight: backlight {
|
||||
+ compatible = "pwm-backlight";
|
||||
+ pwms = <&pwm 0 50000 0>;
|
||||
+ brightness-levels = <0 5 10 15 20 30 40 55 70 85 100>;
|
||||
+ default-brightness-level = <2>;
|
||||
+ enable-gpios = <&pio 3 23 GPIO_ACTIVE_HIGH>; /* PD23 */
|
||||
};
|
||||
|
||||
backlight: backlight {
|
||||
@@ -51,6 +60,17 @@
|
||||
};
|
||||
};
|
||||
|
||||
+ hdmi-connector {
|
||||
+ compatible = "hdmi-connector";
|
||||
+ type = "a";
|
||||
+
|
||||
+ port {
|
||||
+ hdmi_con_in: endpoint {
|
||||
+ remote-endpoint = <&hdmi_out_con>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
@@ -100,6 +120,16 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+&de {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&ehci0 {
|
||||
+ phys = <&usbphy 0>;
|
||||
+ phy-names = "usb";
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&ehci1 {
|
||||
status = "okay";
|
||||
};
|
||||
@@ -133,6 +163,21 @@
|
||||
};
|
||||
};
|
||||
|
||||
+&hdmi {
|
||||
+ hvcc-supply = <®_dldo1>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&hdmi_out {
|
||||
+ hdmi_out_con: endpoint {
|
||||
+ remote-endpoint = <&hdmi_con_in>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&i2s2 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&mixer0 {
|
||||
status = "okay";
|
||||
};
|
||||
@@ -153,6 +216,12 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+&ohci0 {
|
||||
+ phys = <&usbphy 0>;
|
||||
+ phy-names = "usb";
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&ohci1 {
|
||||
status = "okay";
|
||||
};
|
||||
@@ -173,6 +242,29 @@
|
||||
};
|
||||
};
|
||||
|
||||
+&sound {
|
||||
+ status = "okay";
|
||||
+ simple-audio-card,aux-devs = <&codec_analog>, <&speaker_amp>;
|
||||
+ simple-audio-card,widgets = "Microphone", "Internal Microphone Left",
|
||||
+ "Microphone", "Internal Microphone Right",
|
||||
+ "Headphone", "Headphone Jack",
|
||||
+ "Speaker", "Internal Speaker";
|
||||
+ simple-audio-card,routing =
|
||||
+ "Left DAC", "AIF1 Slot 0 Left",
|
||||
+ "Right DAC", "AIF1 Slot 0 Right",
|
||||
+ "Speaker Amp INL", "LINEOUT",
|
||||
+ "Speaker Amp INR", "LINEOUT",
|
||||
+ "Internal Speaker", "Speaker Amp OUTL",
|
||||
+ "Internal Speaker", "Speaker Amp OUTR",
|
||||
+ "Headphone Jack", "HP",
|
||||
+ "AIF1 Slot 0 Left ADC", "Left ADC",
|
||||
+ "AIF1 Slot 0 Right ADC", "Right ADC",
|
||||
+ "Internal Microphone Left", "MBIAS",
|
||||
+ "MIC1", "Internal Microphone Left",
|
||||
+ "Internal Microphone Right", "HBIAS",
|
||||
+ "MIC2", "Internal Microphone Right";
|
||||
+};
|
||||
+
|
||||
#include "axp803.dtsi"
|
||||
|
||||
&ac_power_supply {
|
||||
@@ -319,12 +411,34 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+&hdmi_sound {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&uart0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&uart0_pb_pins>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+&uart1 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>;
|
||||
+ status = "okay";
|
||||
+
|
||||
+ bluetooth {
|
||||
+ compatible = "realtek,rtl8723bs-bt";
|
||||
+ reset-gpios = <&r_pio 0 4 GPIO_ACTIVE_LOW>; /* PL4 */
|
||||
+ device-wake-gpios = <&r_pio 0 5 GPIO_ACTIVE_HIGH>; /* PL5 */
|
||||
+ host-wake-gpios = <&r_pio 0 6 GPIO_ACTIVE_HIGH>; /* PL6 */
|
||||
+ firmware-postfix = "teres";
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&usb_otg {
|
||||
+ dr_mode = "host";
|
||||
+};
|
||||
+
|
||||
&usbphy {
|
||||
usb1_vbus-supply = <®_usb1_vbus>;
|
||||
status = "okay";
|
|
@ -1,55 +0,0 @@
|
|||
From 5b367397da1947fcbf6ed1091c351808218e59bc Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Thu, 12 Jan 2017 16:34:57 +0100
|
||||
Subject: [PATCH 01/82] clk: sunxi-ng: Set maximum M = 1 for H3 pll-cpux clock
|
||||
|
||||
When using M factor greater than 1 system is experiencing
|
||||
occasional lockups.
|
||||
|
||||
This change was verified to fix lockups with PLL stress
|
||||
tester available at https://github.com/megous/h3-firmware.
|
||||
|
||||
Note that M factor must not be used outside the kernel
|
||||
either, so for example u-boot needs a similar patch.
|
||||
---
|
||||
drivers/clk/sunxi-ng/ccu-sun8i-h3.c | 24 +++++++++++++++---------
|
||||
1 file changed, 15 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c
|
||||
index 77ed0b0ba681..8d47742def49 100644
|
||||
--- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c
|
||||
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c
|
||||
@@ -30,15 +30,21 @@
|
||||
|
||||
#include "ccu-sun8i-h3.h"
|
||||
|
||||
-static SUNXI_CCU_NKMP_WITH_GATE_LOCK(pll_cpux_clk, "pll-cpux",
|
||||
- "osc24M", 0x000,
|
||||
- 8, 5, /* N */
|
||||
- 4, 2, /* K */
|
||||
- 0, 2, /* M */
|
||||
- 16, 2, /* P */
|
||||
- BIT(31), /* gate */
|
||||
- BIT(28), /* lock */
|
||||
- CLK_SET_RATE_UNGATE);
|
||||
+static struct ccu_nkmp pll_cpux_clk = {
|
||||
+ .enable = BIT(31),
|
||||
+ .lock = BIT(28),
|
||||
+ .n = _SUNXI_CCU_MULT(8, 5),
|
||||
+ .k = _SUNXI_CCU_MULT(4, 2),
|
||||
+ .m = _SUNXI_CCU_DIV_MAX(0, 2, 1),
|
||||
+ .p = _SUNXI_CCU_DIV(16, 2),
|
||||
+ .common = {
|
||||
+ .reg = 0x000,
|
||||
+ .hw.init = CLK_HW_INIT("pll-cpux",
|
||||
+ "osc24M",
|
||||
+ &ccu_nkmp_ops,
|
||||
+ CLK_SET_RATE_UNGATE),
|
||||
+ },
|
||||
+};
|
||||
|
||||
/*
|
||||
* The Audio PLL is supposed to have 4 outputs: 3 fixed factors from
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
From 9b15c5248e430f418621414f876170f08ca0a2cd Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Thu, 12 Jan 2017 16:37:24 +0100
|
||||
Subject: [PATCH 02/82] clk: sunxi-ng: Allow to limit the use of NKMP clock's P
|
||||
factor
|
||||
|
||||
Some SoCs mandate the maximum clock rate for which the use
|
||||
of postdivider P factor is allowed. Allow to configure maximum
|
||||
clock rate.
|
||||
|
||||
Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
---
|
||||
drivers/clk/sunxi-ng/ccu_nkmp.c | 13 ++++++++-----
|
||||
drivers/clk/sunxi-ng/ccu_nkmp.h | 1 +
|
||||
2 files changed, 9 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.c b/drivers/clk/sunxi-ng/ccu_nkmp.c
|
||||
index 1ad53d1016a3..080bf4a4ace6 100644
|
||||
--- a/drivers/clk/sunxi-ng/ccu_nkmp.c
|
||||
+++ b/drivers/clk/sunxi-ng/ccu_nkmp.c
|
||||
@@ -33,16 +33,19 @@ static unsigned long ccu_nkmp_calc_rate(unsigned long parent,
|
||||
}
|
||||
|
||||
static void ccu_nkmp_find_best(unsigned long parent, unsigned long rate,
|
||||
- struct _ccu_nkmp *nkmp)
|
||||
+ struct _ccu_nkmp *nkmp, struct ccu_nkmp *_nkmp)
|
||||
{
|
||||
unsigned long best_rate = 0;
|
||||
unsigned long best_n = 0, best_k = 0, best_m = 0, best_p = 0;
|
||||
- unsigned long _n, _k, _m, _p;
|
||||
+ unsigned long _n, _k, _m, _p, _max_p;
|
||||
+
|
||||
+ _max_p = (_nkmp->max_rate_for_p == 0 || rate <= _nkmp->max_rate_for_p) ?
|
||||
+ nkmp->max_p : nkmp->min_p;
|
||||
|
||||
for (_k = nkmp->min_k; _k <= nkmp->max_k; _k++) {
|
||||
for (_n = nkmp->min_n; _n <= nkmp->max_n; _n++) {
|
||||
for (_m = nkmp->min_m; _m <= nkmp->max_m; _m++) {
|
||||
- for (_p = nkmp->min_p; _p <= nkmp->max_p; _p <<= 1) {
|
||||
+ for (_p = nkmp->min_p; _p <= _max_p; _p <<= 1) {
|
||||
unsigned long tmp_rate;
|
||||
|
||||
tmp_rate = ccu_nkmp_calc_rate(parent,
|
||||
@@ -146,7 +149,7 @@ static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
_nkmp.min_p = 1;
|
||||
_nkmp.max_p = nkmp->p.max ?: 1 << ((1 << nkmp->p.width) - 1);
|
||||
|
||||
- ccu_nkmp_find_best(*parent_rate, rate, &_nkmp);
|
||||
+ ccu_nkmp_find_best(*parent_rate, rate, &_nkmp, nkmp);
|
||||
|
||||
rate = ccu_nkmp_calc_rate(*parent_rate, _nkmp.n, _nkmp.k,
|
||||
_nkmp.m, _nkmp.p);
|
||||
@@ -177,7 +180,7 @@ static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
_nkmp.min_p = 1;
|
||||
_nkmp.max_p = nkmp->p.max ?: 1 << ((1 << nkmp->p.width) - 1);
|
||||
|
||||
- ccu_nkmp_find_best(parent_rate, rate, &_nkmp);
|
||||
+ ccu_nkmp_find_best(parent_rate, rate, &_nkmp, nkmp);
|
||||
|
||||
if (nkmp->n.width)
|
||||
n_mask = GENMASK(nkmp->n.width + nkmp->n.shift - 1,
|
||||
diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.h b/drivers/clk/sunxi-ng/ccu_nkmp.h
|
||||
index 6940503e7fc4..bbea3e5ed6fb 100644
|
||||
--- a/drivers/clk/sunxi-ng/ccu_nkmp.h
|
||||
+++ b/drivers/clk/sunxi-ng/ccu_nkmp.h
|
||||
@@ -33,6 +33,7 @@ struct ccu_nkmp {
|
||||
struct ccu_mult_internal k;
|
||||
struct ccu_div_internal m;
|
||||
struct ccu_div_internal p;
|
||||
+ unsigned long max_rate_for_p;
|
||||
|
||||
unsigned int fixed_post_div;
|
||||
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
From d46f1f53618ceffa33a5920802a9247337fd3ff3 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Wed, 5 Apr 2017 15:43:48 +0200
|
||||
Subject: [PATCH 03/82] clk: sunxi-ng: Limit pll_cpux P factor for rates >
|
||||
288MHz on H3
|
||||
|
||||
Datasheet for H3 mandates that CPUX PLL must not use postdivider
|
||||
(P factor must be 1) for clock rates above 288MHz.
|
||||
|
||||
Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
---
|
||||
drivers/clk/sunxi-ng/ccu-sun8i-h3.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c
|
||||
index 8d47742def49..7cc9467f373f 100644
|
||||
--- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c
|
||||
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c
|
||||
@@ -37,6 +37,7 @@ static struct ccu_nkmp pll_cpux_clk = {
|
||||
.k = _SUNXI_CCU_MULT(4, 2),
|
||||
.m = _SUNXI_CCU_DIV_MAX(0, 2, 1),
|
||||
.p = _SUNXI_CCU_DIV(16, 2),
|
||||
+ .max_rate_for_p = 288000000,
|
||||
.common = {
|
||||
.reg = 0x000,
|
||||
.hw.init = CLK_HW_INIT("pll-cpux",
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,295 +0,0 @@
|
|||
From e4092ba9553a4680f2b28334f87e2c97a084f95e Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Sat, 25 Jun 2016 21:51:05 +0200
|
||||
Subject: [PATCH 04/82] thermal: sun8i_ths: Add support for the thermal sensor
|
||||
on Allwinner H3
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This patch adds support for the sun8i thermal sensor on
|
||||
Allwinner H3 SoC.
|
||||
|
||||
Signed-off-by: Ondřej Jirman <megous@megous.com>
|
||||
---
|
||||
drivers/thermal/Kconfig | 7 ++
|
||||
drivers/thermal/Makefile | 1 +
|
||||
drivers/thermal/sun8i_ths.c | 239 ++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 247 insertions(+)
|
||||
create mode 100644 drivers/thermal/sun8i_ths.c
|
||||
|
||||
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
|
||||
index 0e69edc77d18..5125c5e8f7ce 100644
|
||||
--- a/drivers/thermal/Kconfig
|
||||
+++ b/drivers/thermal/Kconfig
|
||||
@@ -420,6 +420,13 @@ depends on ARCH_BCM || ARCH_BRCMSTB || ARCH_BCM2835 || COMPILE_TEST
|
||||
source "drivers/thermal/broadcom/Kconfig"
|
||||
endmenu
|
||||
|
||||
+config SUN8I_THS
|
||||
+ tristate "Thermal sensor driver for Allwinner H3"
|
||||
+ depends on MACH_SUN8I || (ARM64 && ARCH_SUNXI)
|
||||
+ depends on OF
|
||||
+ help
|
||||
+ Enable this to support thermal reporting on some newer Allwinner SoCs.
|
||||
+
|
||||
menu "Texas Instruments thermal drivers"
|
||||
depends on ARCH_HAS_BANDGAP || COMPILE_TEST
|
||||
depends on HAS_IOMEM
|
||||
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
|
||||
index 610344eb3e03..dc8a24fddba9 100644
|
||||
--- a/drivers/thermal/Makefile
|
||||
+++ b/drivers/thermal/Makefile
|
||||
@@ -61,3 +61,4 @@ obj-$(CONFIG_MTK_THERMAL) += mtk_thermal.o
|
||||
obj-$(CONFIG_GENERIC_ADC_THERMAL) += thermal-generic-adc.o
|
||||
obj-$(CONFIG_ZX2967_THERMAL) += zx2967_thermal.o
|
||||
obj-$(CONFIG_UNIPHIER_THERMAL) += uniphier_thermal.o
|
||||
+obj-$(CONFIG_SUN8I_THS) += sun8i_ths.o
|
||||
diff --git a/drivers/thermal/sun8i_ths.c b/drivers/thermal/sun8i_ths.c
|
||||
new file mode 100644
|
||||
index 000000000000..cfe7d1073b8c
|
||||
--- /dev/null
|
||||
+++ b/drivers/thermal/sun8i_ths.c
|
||||
@@ -0,0 +1,239 @@
|
||||
+/*
|
||||
+ * Thermal sensor driver for Allwinner H3 SoC
|
||||
+ *
|
||||
+ * Copyright (C) 2016 Ondřej Jirman
|
||||
+ * Based on the work of Josef Gajdusek <atx@atx.name>
|
||||
+ *
|
||||
+ * This software is licensed under the terms of the GNU General Public
|
||||
+ * License version 2, as published by the Free Software Foundation, and
|
||||
+ * may be copied, distributed, and modified under those terms.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/io.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of_device.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/reset.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/thermal.h>
|
||||
+#include <linux/printk.h>
|
||||
+
|
||||
+#define THS_H3_CTRL0 0x00
|
||||
+#define THS_H3_CTRL2 0x40
|
||||
+#define THS_H3_INT_CTRL 0x44
|
||||
+#define THS_H3_STAT 0x48
|
||||
+#define THS_H3_FILTER 0x70
|
||||
+#define THS_H3_CDATA 0x74
|
||||
+#define THS_H3_DATA 0x80
|
||||
+
|
||||
+#define THS_H3_CTRL0_SENSOR_ACQ0(x) (x)
|
||||
+#define THS_H3_CTRL2_SENSE_EN BIT(0)
|
||||
+#define THS_H3_CTRL2_SENSOR_ACQ1(x) ((x) << 16)
|
||||
+#define THS_H3_INT_CTRL_DATA_IRQ_EN BIT(8)
|
||||
+#define THS_H3_INT_CTRL_THERMAL_PER(x) ((x) << 12)
|
||||
+#define THS_H3_STAT_DATA_IRQ_STS BIT(8)
|
||||
+#define THS_H3_FILTER_TYPE(x) ((x) << 0)
|
||||
+#define THS_H3_FILTER_EN BIT(2)
|
||||
+
|
||||
+#define THS_H3_CLK_IN 40000000 /* Hz */
|
||||
+#define THS_H3_DATA_PERIOD 330 /* ms */
|
||||
+
|
||||
+#define THS_H3_FILTER_TYPE_VALUE 2 /* average over 2^(n+1) samples */
|
||||
+#define THS_H3_FILTER_DIV (1 << (THS_H3_FILTER_TYPE_VALUE + 1))
|
||||
+#define THS_H3_INT_CTRL_THERMAL_PER_VALUE \
|
||||
+ (THS_H3_DATA_PERIOD * (THS_H3_CLK_IN / 1000) / THS_H3_FILTER_DIV / 4096 - 1)
|
||||
+#define THS_H3_CTRL0_SENSOR_ACQ0_VALUE 0x3f /* 16us */
|
||||
+#define THS_H3_CTRL2_SENSOR_ACQ1_VALUE 0x3f
|
||||
+
|
||||
+struct sun8i_ths_data {
|
||||
+ struct reset_control *reset;
|
||||
+ struct clk *clk;
|
||||
+ struct clk *busclk;
|
||||
+ void __iomem *regs;
|
||||
+ struct thermal_zone_device *tzd;
|
||||
+ u32 temp;
|
||||
+};
|
||||
+
|
||||
+static int sun8i_ths_get_temp(void *_data, int *out)
|
||||
+{
|
||||
+ struct sun8i_ths_data *data = _data;
|
||||
+
|
||||
+ if (data->temp == 0)
|
||||
+ return -EBUSY;
|
||||
+
|
||||
+ /* Formula and parameters from the Allwinner 3.4 kernel */
|
||||
+ *out = 217000 - (int)((data->temp * 1000000) / 8253);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static irqreturn_t sun8i_ths_irq_thread(int irq, void *_data)
|
||||
+{
|
||||
+ struct sun8i_ths_data *data = _data;
|
||||
+
|
||||
+ writel(THS_H3_STAT_DATA_IRQ_STS, data->regs + THS_H3_STAT);
|
||||
+
|
||||
+ data->temp = readl(data->regs + THS_H3_DATA);
|
||||
+ if (data->temp)
|
||||
+ thermal_zone_device_update(data->tzd, THERMAL_EVENT_TEMP_SAMPLE);
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static void sun8i_ths_h3_init(struct sun8i_ths_data *data)
|
||||
+{
|
||||
+ writel(THS_H3_CTRL0_SENSOR_ACQ0(THS_H3_CTRL0_SENSOR_ACQ0_VALUE),
|
||||
+ data->regs + THS_H3_CTRL0);
|
||||
+ writel(THS_H3_FILTER_EN | THS_H3_FILTER_TYPE(THS_H3_FILTER_TYPE_VALUE),
|
||||
+ data->regs + THS_H3_FILTER);
|
||||
+ writel(THS_H3_CTRL2_SENSOR_ACQ1(THS_H3_CTRL2_SENSOR_ACQ1_VALUE) |
|
||||
+ THS_H3_CTRL2_SENSE_EN,
|
||||
+ data->regs + THS_H3_CTRL2);
|
||||
+ writel(THS_H3_INT_CTRL_THERMAL_PER(THS_H3_INT_CTRL_THERMAL_PER_VALUE) |
|
||||
+ THS_H3_INT_CTRL_DATA_IRQ_EN,
|
||||
+ data->regs + THS_H3_INT_CTRL);
|
||||
+}
|
||||
+
|
||||
+static const struct thermal_zone_of_device_ops sun8i_ths_thermal_ops = {
|
||||
+ .get_temp = sun8i_ths_get_temp,
|
||||
+};
|
||||
+
|
||||
+static int sun8i_ths_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct sun8i_ths_data *data;
|
||||
+ struct resource *res;
|
||||
+ int ret;
|
||||
+ int irq;
|
||||
+
|
||||
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
|
||||
+ if (!data)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ if (!res) {
|
||||
+ dev_err(&pdev->dev, "no memory resources defined\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ data->regs = devm_ioremap_resource(&pdev->dev, res);
|
||||
+ if (IS_ERR(data->regs)) {
|
||||
+ ret = PTR_ERR(data->regs);
|
||||
+ dev_err(&pdev->dev, "failed to ioremap THS registers: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ irq = platform_get_irq(pdev, 0);
|
||||
+ if (irq < 0) {
|
||||
+ dev_err(&pdev->dev, "failed to get IRQ: %d\n", irq);
|
||||
+ return irq;
|
||||
+ }
|
||||
+
|
||||
+ ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
|
||||
+ sun8i_ths_irq_thread, IRQF_ONESHOT,
|
||||
+ dev_name(&pdev->dev), data);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ data->busclk = devm_clk_get(&pdev->dev, "ahb");
|
||||
+ if (IS_ERR(data->busclk)) {
|
||||
+ ret = PTR_ERR(data->busclk);
|
||||
+ dev_err(&pdev->dev, "failed to get ahb clk: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ data->clk = devm_clk_get(&pdev->dev, "ths");
|
||||
+ if (IS_ERR(data->clk)) {
|
||||
+ ret = PTR_ERR(data->clk);
|
||||
+ dev_err(&pdev->dev, "failed to get ths clk: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ data->reset = devm_reset_control_get(&pdev->dev, "ahb");
|
||||
+ if (IS_ERR(data->reset)) {
|
||||
+ ret = PTR_ERR(data->reset);
|
||||
+ dev_err(&pdev->dev, "failed to get reset: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = reset_control_deassert(data->reset);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "reset deassert failed: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = clk_prepare_enable(data->busclk);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "failed to enable bus clk: %d\n", ret);
|
||||
+ goto err_assert_reset;
|
||||
+ }
|
||||
+
|
||||
+ ret = clk_prepare_enable(data->clk);
|
||||
+ if (ret) {
|
||||
+ dev_err(&pdev->dev, "failed to enable ths clk: %d\n", ret);
|
||||
+ goto err_disable_bus;
|
||||
+ }
|
||||
+
|
||||
+ ret = clk_set_rate(data->clk, THS_H3_CLK_IN);
|
||||
+ if (ret)
|
||||
+ goto err_disable_ths;
|
||||
+
|
||||
+ data->tzd = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, data,
|
||||
+ &sun8i_ths_thermal_ops);
|
||||
+ if (IS_ERR(data->tzd)) {
|
||||
+ ret = PTR_ERR(data->tzd);
|
||||
+ dev_err(&pdev->dev, "failed to register thermal zone: %d\n",
|
||||
+ ret);
|
||||
+ goto err_disable_ths;
|
||||
+ }
|
||||
+
|
||||
+ sun8i_ths_h3_init(data);
|
||||
+
|
||||
+ platform_set_drvdata(pdev, data);
|
||||
+ return 0;
|
||||
+
|
||||
+err_disable_ths:
|
||||
+ clk_disable_unprepare(data->clk);
|
||||
+err_disable_bus:
|
||||
+ clk_disable_unprepare(data->busclk);
|
||||
+err_assert_reset:
|
||||
+ reset_control_assert(data->reset);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int sun8i_ths_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct sun8i_ths_data *data = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ reset_control_assert(data->reset);
|
||||
+ clk_disable_unprepare(data->clk);
|
||||
+ clk_disable_unprepare(data->busclk);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id sun8i_ths_id_table[] = {
|
||||
+ { .compatible = "allwinner,sun8i-h3-ths", },
|
||||
+ { /* sentinel */ },
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, sun8i_ths_id_table);
|
||||
+
|
||||
+static struct platform_driver sun8i_ths_driver = {
|
||||
+ .probe = sun8i_ths_probe,
|
||||
+ .remove = sun8i_ths_remove,
|
||||
+ .driver = {
|
||||
+ .name = "sun8i_ths",
|
||||
+ .of_match_table = sun8i_ths_id_table,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+module_platform_driver(sun8i_ths_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("Ondřej Jirman <megous@megous.com>");
|
||||
+MODULE_DESCRIPTION("Thermal sensor driver for Allwinner H3 SoC");
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,498 +0,0 @@
|
|||
From 9da4c28e6a7963f67e2ca05098683445a1571538 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Tue, 14 Nov 2017 17:15:54 +0100
|
||||
Subject: [PATCH 05/82] thermal: sun8i: Add support for A83T thermal sensors
|
||||
|
||||
Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
---
|
||||
drivers/thermal/sun8i_ths.c | 371 ++++++++++++++++++++++++++----------
|
||||
1 file changed, 274 insertions(+), 97 deletions(-)
|
||||
|
||||
diff --git a/drivers/thermal/sun8i_ths.c b/drivers/thermal/sun8i_ths.c
|
||||
index cfe7d1073b8c..2fda940da4cc 100644
|
||||
--- a/drivers/thermal/sun8i_ths.c
|
||||
+++ b/drivers/thermal/sun8i_ths.c
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * Thermal sensor driver for Allwinner H3 SoC
|
||||
+ * Thermal sensor driver for Allwinner SUN8I SoC
|
||||
*
|
||||
* Copyright (C) 2016 Ondřej Jirman
|
||||
* Based on the work of Josef Gajdusek <atx@atx.name>
|
||||
@@ -26,79 +26,174 @@
|
||||
#include <linux/thermal.h>
|
||||
#include <linux/printk.h>
|
||||
|
||||
-#define THS_H3_CTRL0 0x00
|
||||
-#define THS_H3_CTRL2 0x40
|
||||
-#define THS_H3_INT_CTRL 0x44
|
||||
-#define THS_H3_STAT 0x48
|
||||
-#define THS_H3_FILTER 0x70
|
||||
-#define THS_H3_CDATA 0x74
|
||||
-#define THS_H3_DATA 0x80
|
||||
-
|
||||
-#define THS_H3_CTRL0_SENSOR_ACQ0(x) (x)
|
||||
-#define THS_H3_CTRL2_SENSE_EN BIT(0)
|
||||
-#define THS_H3_CTRL2_SENSOR_ACQ1(x) ((x) << 16)
|
||||
-#define THS_H3_INT_CTRL_DATA_IRQ_EN BIT(8)
|
||||
-#define THS_H3_INT_CTRL_THERMAL_PER(x) ((x) << 12)
|
||||
-#define THS_H3_STAT_DATA_IRQ_STS BIT(8)
|
||||
-#define THS_H3_FILTER_TYPE(x) ((x) << 0)
|
||||
-#define THS_H3_FILTER_EN BIT(2)
|
||||
-
|
||||
-#define THS_H3_CLK_IN 40000000 /* Hz */
|
||||
-#define THS_H3_DATA_PERIOD 330 /* ms */
|
||||
-
|
||||
-#define THS_H3_FILTER_TYPE_VALUE 2 /* average over 2^(n+1) samples */
|
||||
-#define THS_H3_FILTER_DIV (1 << (THS_H3_FILTER_TYPE_VALUE + 1))
|
||||
-#define THS_H3_INT_CTRL_THERMAL_PER_VALUE \
|
||||
- (THS_H3_DATA_PERIOD * (THS_H3_CLK_IN / 1000) / THS_H3_FILTER_DIV / 4096 - 1)
|
||||
-#define THS_H3_CTRL0_SENSOR_ACQ0_VALUE 0x3f /* 16us */
|
||||
-#define THS_H3_CTRL2_SENSOR_ACQ1_VALUE 0x3f
|
||||
+#define THS_SUN8I_CTRL0 0x00
|
||||
+#define THS_SUN8I_CTRL2 0x40
|
||||
+#define THS_SUN8I_INT_CTRL 0x44
|
||||
+#define THS_SUN8I_STAT 0x48
|
||||
+#define THS_SUN8I_FILTER 0x70
|
||||
+#define THS_SUN8I_CDATA01 0x74
|
||||
+#define THS_SUN8I_CDATA2 0x78
|
||||
+#define THS_SUN8I_DATA0 0x80
|
||||
+#define THS_SUN8I_DATA1 0x84
|
||||
+#define THS_SUN8I_DATA2 0x88
|
||||
+
|
||||
+#define THS_SUN8I_CTRL0_SENSOR_ACQ0(x) (x)
|
||||
+#define THS_SUN8I_CTRL2_SENSE_EN0 BIT(0)
|
||||
+#define THS_SUN8I_CTRL2_SENSE_EN1 BIT(1)
|
||||
+#define THS_SUN8I_CTRL2_SENSE_EN2 BIT(2)
|
||||
+#define THS_SUN8I_CTRL2_SENSOR_ACQ1(x) ((x) << 16)
|
||||
+#define THS_SUN8I_INT_CTRL_DATA0_IRQ_EN BIT(8)
|
||||
+#define THS_SUN8I_INT_CTRL_DATA1_IRQ_EN BIT(9)
|
||||
+#define THS_SUN8I_INT_CTRL_DATA2_IRQ_EN BIT(10)
|
||||
+#define THS_SUN8I_INT_CTRL_THERMAL_PER(x) ((x) << 12)
|
||||
+#define THS_SUN8I_STAT_DATA0_IRQ_STS BIT(8)
|
||||
+#define THS_SUN8I_STAT_DATA1_IRQ_STS BIT(9)
|
||||
+#define THS_SUN8I_STAT_DATA2_IRQ_STS BIT(10)
|
||||
+#define THS_SUN8I_STAT_CLEAR 0x777
|
||||
+#define THS_SUN8I_FILTER_TYPE(x) ((x) << 0)
|
||||
+#define THS_SUN8I_FILTER_EN BIT(2)
|
||||
+
|
||||
+#define THS_SUN8I_CLK_IN 40000000 /* Hz */
|
||||
+#define THS_SUN8I_DATA_PERIOD 330 /* ms */
|
||||
+#define THS_SUN8I_FILTER_TYPE_VALUE 2 /* average over 2^(n+1) samples */
|
||||
+
|
||||
+//XXX: this formula doesn't work for A83T very well
|
||||
+//XXX: A83T is getting slower readings out of this (1s interval?)
|
||||
+//perhaps configure this in sun8i_ths_desc
|
||||
+#define THS_SUN8I_FILTER_DIV (1 << (THS_SUN8I_FILTER_TYPE_VALUE + 1))
|
||||
+#define THS_SUN8I_INT_CTRL_THERMAL_PER_VALUE \
|
||||
+ (THS_SUN8I_DATA_PERIOD * (THS_SUN8I_CLK_IN / 1000) / \
|
||||
+ THS_SUN8I_FILTER_DIV / 4096 - 1)
|
||||
+
|
||||
+#define THS_SUN8I_CTRL0_SENSOR_ACQ0_VALUE 0x3f /* 16us */
|
||||
+#define THS_SUN8I_CTRL2_SENSOR_ACQ1_VALUE 0x3f
|
||||
+
|
||||
+#define SUN8I_THS_MAX_TZDS 3
|
||||
+
|
||||
+struct sun8i_ths_sensor_desc {
|
||||
+ u32 data_int_en;
|
||||
+ u32 data_int_flag;
|
||||
+ u32 data_offset;
|
||||
+ u32 sense_en;
|
||||
+};
|
||||
+
|
||||
+struct sun8i_ths_desc {
|
||||
+ int num_sensors;
|
||||
+ struct sun8i_ths_sensor_desc *sensors;
|
||||
+ int (*calc_temp)(u32 reg_val);
|
||||
+ bool has_cal1;
|
||||
+};
|
||||
+
|
||||
+struct sun8i_ths_tzd {
|
||||
+ struct sun8i_ths_data *data;
|
||||
+ struct thermal_zone_device *tzd;
|
||||
+ u32 temp;
|
||||
+};
|
||||
|
||||
struct sun8i_ths_data {
|
||||
+ struct device *dev;
|
||||
struct reset_control *reset;
|
||||
struct clk *clk;
|
||||
struct clk *busclk;
|
||||
void __iomem *regs;
|
||||
- struct thermal_zone_device *tzd;
|
||||
- u32 temp;
|
||||
+ void __iomem *cal_regs;
|
||||
+ struct sun8i_ths_desc *desc;
|
||||
+ struct sun8i_ths_tzd tzds[SUN8I_THS_MAX_TZDS];
|
||||
};
|
||||
|
||||
+static int sun8i_ths_calc_temp_h3(u32 reg_val)
|
||||
+{
|
||||
+ uint64_t temp = (uint64_t)reg_val * 1000000ll;
|
||||
+
|
||||
+ do_div(temp, 8253);
|
||||
+
|
||||
+ return 217000 - (int)temp;
|
||||
+}
|
||||
+
|
||||
+static int sun8i_ths_calc_temp_a83t(u32 reg_val)
|
||||
+{
|
||||
+ uint64_t temp = (uint64_t)reg_val * 1000000ll;
|
||||
+
|
||||
+ do_div(temp, 14186);
|
||||
+
|
||||
+ return 192000 - (int)temp;
|
||||
+}
|
||||
+
|
||||
static int sun8i_ths_get_temp(void *_data, int *out)
|
||||
{
|
||||
- struct sun8i_ths_data *data = _data;
|
||||
+ struct sun8i_ths_tzd *tzd = _data;
|
||||
+ struct sun8i_ths_data *data = tzd->data;
|
||||
|
||||
- if (data->temp == 0)
|
||||
+ if (tzd->temp == 0)
|
||||
return -EBUSY;
|
||||
|
||||
- /* Formula and parameters from the Allwinner 3.4 kernel */
|
||||
- *out = 217000 - (int)((data->temp * 1000000) / 8253);
|
||||
+ *out = data->desc->calc_temp(tzd->temp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static irqreturn_t sun8i_ths_irq_thread(int irq, void *_data)
|
||||
{
|
||||
struct sun8i_ths_data *data = _data;
|
||||
-
|
||||
- writel(THS_H3_STAT_DATA_IRQ_STS, data->regs + THS_H3_STAT);
|
||||
-
|
||||
- data->temp = readl(data->regs + THS_H3_DATA);
|
||||
- if (data->temp)
|
||||
- thermal_zone_device_update(data->tzd, THERMAL_EVENT_TEMP_SAMPLE);
|
||||
+ struct sun8i_ths_tzd *tzd;
|
||||
+ struct sun8i_ths_sensor_desc *zdesc;
|
||||
+ int i;
|
||||
+ u32 status;
|
||||
+
|
||||
+ status = readl(data->regs + THS_SUN8I_STAT);
|
||||
+ writel(THS_SUN8I_STAT_CLEAR, data->regs + THS_SUN8I_STAT);
|
||||
+
|
||||
+ for (i = 0; i < data->desc->num_sensors; i++) {
|
||||
+ tzd = &data->tzds[i];
|
||||
+ zdesc = &data->desc->sensors[i];
|
||||
+
|
||||
+ if (status & zdesc->data_int_flag) {
|
||||
+ tzd->temp = readl(data->regs + zdesc->data_offset);
|
||||
+ if (tzd->temp)
|
||||
+ thermal_zone_device_update(tzd->tzd,
|
||||
+ THERMAL_EVENT_TEMP_SAMPLE);
|
||||
+ }
|
||||
+ }
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
-static void sun8i_ths_h3_init(struct sun8i_ths_data *data)
|
||||
+static void sun8i_ths_init(struct sun8i_ths_data *data)
|
||||
{
|
||||
- writel(THS_H3_CTRL0_SENSOR_ACQ0(THS_H3_CTRL0_SENSOR_ACQ0_VALUE),
|
||||
- data->regs + THS_H3_CTRL0);
|
||||
- writel(THS_H3_FILTER_EN | THS_H3_FILTER_TYPE(THS_H3_FILTER_TYPE_VALUE),
|
||||
- data->regs + THS_H3_FILTER);
|
||||
- writel(THS_H3_CTRL2_SENSOR_ACQ1(THS_H3_CTRL2_SENSOR_ACQ1_VALUE) |
|
||||
- THS_H3_CTRL2_SENSE_EN,
|
||||
- data->regs + THS_H3_CTRL2);
|
||||
- writel(THS_H3_INT_CTRL_THERMAL_PER(THS_H3_INT_CTRL_THERMAL_PER_VALUE) |
|
||||
- THS_H3_INT_CTRL_DATA_IRQ_EN,
|
||||
- data->regs + THS_H3_INT_CTRL);
|
||||
+ int i;
|
||||
+ u32 int_ctrl = 0;
|
||||
+ u32 ctrl2 = 0;
|
||||
+
|
||||
+ writel(THS_SUN8I_CTRL0_SENSOR_ACQ0(THS_SUN8I_CTRL0_SENSOR_ACQ0_VALUE),
|
||||
+ data->regs + THS_SUN8I_CTRL0);
|
||||
+ writel(THS_SUN8I_FILTER_EN | THS_SUN8I_FILTER_TYPE(THS_SUN8I_FILTER_TYPE_VALUE),
|
||||
+ data->regs + THS_SUN8I_FILTER);
|
||||
+
|
||||
+ ctrl2 |= THS_SUN8I_CTRL2_SENSOR_ACQ1(THS_SUN8I_CTRL2_SENSOR_ACQ1_VALUE);
|
||||
+ int_ctrl |= THS_SUN8I_INT_CTRL_THERMAL_PER(THS_SUN8I_INT_CTRL_THERMAL_PER_VALUE);
|
||||
+
|
||||
+ for (i = 0; i < data->desc->num_sensors; i++) {
|
||||
+ ctrl2 |= data->desc->sensors[i].sense_en;
|
||||
+ int_ctrl |= data->desc->sensors[i].data_int_en;
|
||||
+ }
|
||||
+
|
||||
+ if (data->cal_regs) {
|
||||
+ u32 cal0, cal1;
|
||||
+
|
||||
+ cal0 = readl(data->cal_regs);
|
||||
+ if (cal0)
|
||||
+ writel(cal0, data->regs + THS_SUN8I_CDATA01);
|
||||
+
|
||||
+ if (data->desc->has_cal1) {
|
||||
+ cal1 = readl(data->cal_regs + 4);
|
||||
+ if (cal1)
|
||||
+ writel(cal1, data->regs + THS_SUN8I_CDATA2);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ writel(ctrl2, data->regs + THS_SUN8I_CTRL2);
|
||||
+
|
||||
+ /* enable interrupts */
|
||||
+ writel(int_ctrl, data->regs + THS_SUN8I_INT_CTRL);
|
||||
}
|
||||
|
||||
static const struct thermal_zone_of_device_ops sun8i_ths_thermal_ops = {
|
||||
@@ -108,100 +203,135 @@ static const struct thermal_zone_of_device_ops sun8i_ths_thermal_ops = {
|
||||
static int sun8i_ths_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct sun8i_ths_data *data;
|
||||
+ struct device *dev = &pdev->dev;
|
||||
struct resource *res;
|
||||
- int ret;
|
||||
- int irq;
|
||||
+ int ret, irq, i;
|
||||
|
||||
- data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
|
||||
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
+ data->desc = (struct sun8i_ths_desc *)of_device_get_match_data(dev);
|
||||
+ if (data->desc == NULL)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ data->dev = dev;
|
||||
+ platform_set_drvdata(pdev, data);
|
||||
+
|
||||
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ths");
|
||||
if (!res) {
|
||||
- dev_err(&pdev->dev, "no memory resources defined\n");
|
||||
+ dev_err(dev, "no memory resources defined\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- data->regs = devm_ioremap_resource(&pdev->dev, res);
|
||||
+ data->regs = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(data->regs)) {
|
||||
ret = PTR_ERR(data->regs);
|
||||
- dev_err(&pdev->dev, "failed to ioremap THS registers: %d\n", ret);
|
||||
+ dev_err(dev, "failed to ioremap THS registers: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
+ /*XXX: use SRAM device in the future, instead of direct access to regs */
|
||||
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "calibration");
|
||||
+ if (res) {
|
||||
+ data->cal_regs = devm_ioremap_resource(dev, res);
|
||||
+ if (IS_ERR(data->cal_regs)) {
|
||||
+ ret = PTR_ERR(data->cal_regs);
|
||||
+ dev_err(dev, "failed to ioremap calibration SRAM: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0) {
|
||||
- dev_err(&pdev->dev, "failed to get IRQ: %d\n", irq);
|
||||
+ dev_err(dev, "failed to get IRQ: %d\n", irq);
|
||||
return irq;
|
||||
}
|
||||
|
||||
- ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
|
||||
+ ret = devm_request_threaded_irq(dev, irq, NULL,
|
||||
sun8i_ths_irq_thread, IRQF_ONESHOT,
|
||||
- dev_name(&pdev->dev), data);
|
||||
+ dev_name(dev), data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- data->busclk = devm_clk_get(&pdev->dev, "ahb");
|
||||
+ data->busclk = devm_clk_get(dev, "ahb");
|
||||
if (IS_ERR(data->busclk)) {
|
||||
ret = PTR_ERR(data->busclk);
|
||||
- dev_err(&pdev->dev, "failed to get ahb clk: %d\n", ret);
|
||||
- return ret;
|
||||
+ if (ret != -ENOENT) {
|
||||
+ dev_err(dev, "failed to get ahb clk: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ data->busclk = NULL;
|
||||
}
|
||||
|
||||
- data->clk = devm_clk_get(&pdev->dev, "ths");
|
||||
+ data->clk = devm_clk_get(dev, "ths");
|
||||
if (IS_ERR(data->clk)) {
|
||||
ret = PTR_ERR(data->clk);
|
||||
- dev_err(&pdev->dev, "failed to get ths clk: %d\n", ret);
|
||||
- return ret;
|
||||
+ if (ret != -ENOENT) {
|
||||
+ dev_err(dev, "failed to get ths clk: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ data->clk = NULL;
|
||||
}
|
||||
|
||||
- data->reset = devm_reset_control_get(&pdev->dev, "ahb");
|
||||
+ data->reset = devm_reset_control_get_optional(dev, "ahb");
|
||||
if (IS_ERR(data->reset)) {
|
||||
ret = PTR_ERR(data->reset);
|
||||
- dev_err(&pdev->dev, "failed to get reset: %d\n", ret);
|
||||
+ dev_err(dev, "failed to get reset: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = reset_control_deassert(data->reset);
|
||||
if (ret) {
|
||||
- dev_err(&pdev->dev, "reset deassert failed: %d\n", ret);
|
||||
+ dev_err(dev, "reset deassert failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
- ret = clk_prepare_enable(data->busclk);
|
||||
- if (ret) {
|
||||
- dev_err(&pdev->dev, "failed to enable bus clk: %d\n", ret);
|
||||
- goto err_assert_reset;
|
||||
+ if (data->busclk) {
|
||||
+ ret = clk_prepare_enable(data->busclk);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "failed to enable bus clk: %d\n", ret);
|
||||
+ goto err_assert_reset;
|
||||
+ }
|
||||
}
|
||||
|
||||
- ret = clk_prepare_enable(data->clk);
|
||||
- if (ret) {
|
||||
- dev_err(&pdev->dev, "failed to enable ths clk: %d\n", ret);
|
||||
- goto err_disable_bus;
|
||||
- }
|
||||
+ if (data->clk) {
|
||||
+ ret = clk_prepare_enable(data->clk);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "failed to enable ths clk: %d\n", ret);
|
||||
+ goto err_disable_bus;
|
||||
+ }
|
||||
|
||||
- ret = clk_set_rate(data->clk, THS_H3_CLK_IN);
|
||||
- if (ret)
|
||||
- goto err_disable_ths;
|
||||
-
|
||||
- data->tzd = devm_thermal_zone_of_sensor_register(&pdev->dev, 0, data,
|
||||
- &sun8i_ths_thermal_ops);
|
||||
- if (IS_ERR(data->tzd)) {
|
||||
- ret = PTR_ERR(data->tzd);
|
||||
- dev_err(&pdev->dev, "failed to register thermal zone: %d\n",
|
||||
- ret);
|
||||
- goto err_disable_ths;
|
||||
+ ret = clk_set_rate(data->clk, THS_SUN8I_CLK_IN);
|
||||
+ if (ret)
|
||||
+ goto err_disable_ths;
|
||||
}
|
||||
|
||||
- sun8i_ths_h3_init(data);
|
||||
+ for (i = 0; i < data->desc->num_sensors; i++) {
|
||||
+ data->tzds[i].data = data;
|
||||
+ data->tzds[i].tzd =
|
||||
+ devm_thermal_zone_of_sensor_register(dev, i,
|
||||
+ &data->tzds[i],
|
||||
+ &sun8i_ths_thermal_ops);
|
||||
+ if (IS_ERR(data->tzds[i].tzd)) {
|
||||
+ ret = PTR_ERR(data->tzds[i].tzd);
|
||||
+ dev_err(dev,
|
||||
+ "failed to register thermal zone: %d\n", ret);
|
||||
+ goto err_disable_ths;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
- platform_set_drvdata(pdev, data);
|
||||
+ sun8i_ths_init(data);
|
||||
return 0;
|
||||
|
||||
err_disable_ths:
|
||||
- clk_disable_unprepare(data->clk);
|
||||
+ if (data->clk)
|
||||
+ clk_disable_unprepare(data->clk);
|
||||
err_disable_bus:
|
||||
- clk_disable_unprepare(data->busclk);
|
||||
+ if (data->busclk)
|
||||
+ clk_disable_unprepare(data->busclk);
|
||||
err_assert_reset:
|
||||
reset_control_assert(data->reset);
|
||||
return ret;
|
||||
@@ -212,13 +342,60 @@ static int sun8i_ths_remove(struct platform_device *pdev)
|
||||
struct sun8i_ths_data *data = platform_get_drvdata(pdev);
|
||||
|
||||
reset_control_assert(data->reset);
|
||||
- clk_disable_unprepare(data->clk);
|
||||
- clk_disable_unprepare(data->busclk);
|
||||
+ if (data->clk)
|
||||
+ clk_disable_unprepare(data->clk);
|
||||
+ if (data->busclk)
|
||||
+ clk_disable_unprepare(data->busclk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
+struct sun8i_ths_sensor_desc sun8i_ths_h3_sensors[] = {
|
||||
+ {
|
||||
+ .data_int_en = THS_SUN8I_INT_CTRL_DATA0_IRQ_EN,
|
||||
+ .data_int_flag = THS_SUN8I_STAT_DATA0_IRQ_STS,
|
||||
+ .data_offset = THS_SUN8I_DATA0,
|
||||
+ .sense_en = THS_SUN8I_CTRL2_SENSE_EN0,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+struct sun8i_ths_sensor_desc sun8i_ths_a83t_sensors[] = {
|
||||
+ {
|
||||
+ .data_int_en = THS_SUN8I_INT_CTRL_DATA0_IRQ_EN,
|
||||
+ .data_int_flag = THS_SUN8I_STAT_DATA0_IRQ_STS,
|
||||
+ .data_offset = THS_SUN8I_DATA0,
|
||||
+ .sense_en = THS_SUN8I_CTRL2_SENSE_EN0,
|
||||
+ },
|
||||
+ {
|
||||
+ .data_int_en = THS_SUN8I_INT_CTRL_DATA1_IRQ_EN,
|
||||
+ .data_int_flag = THS_SUN8I_STAT_DATA1_IRQ_STS,
|
||||
+ .data_offset = THS_SUN8I_DATA1,
|
||||
+ .sense_en = THS_SUN8I_CTRL2_SENSE_EN1,
|
||||
+ },
|
||||
+ {
|
||||
+ .data_int_en = THS_SUN8I_INT_CTRL_DATA2_IRQ_EN,
|
||||
+ .data_int_flag = THS_SUN8I_STAT_DATA2_IRQ_STS,
|
||||
+ .data_offset = THS_SUN8I_DATA2,
|
||||
+ .sense_en = THS_SUN8I_CTRL2_SENSE_EN2,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static const struct sun8i_ths_desc sun8i_ths_h3_desc = {
|
||||
+ .num_sensors = ARRAY_SIZE(sun8i_ths_h3_sensors),
|
||||
+ .sensors = sun8i_ths_h3_sensors,
|
||||
+ .calc_temp = sun8i_ths_calc_temp_h3,
|
||||
+ .has_cal1 = false,
|
||||
+};
|
||||
+
|
||||
+static const struct sun8i_ths_desc sun8i_ths_a83t_desc = {
|
||||
+ .num_sensors = ARRAY_SIZE(sun8i_ths_a83t_sensors),
|
||||
+ .sensors = sun8i_ths_a83t_sensors,
|
||||
+ .calc_temp = sun8i_ths_calc_temp_a83t,
|
||||
+ .has_cal1 = true,
|
||||
+};
|
||||
+
|
||||
static const struct of_device_id sun8i_ths_id_table[] = {
|
||||
- { .compatible = "allwinner,sun8i-h3-ths", },
|
||||
+ { .compatible = "allwinner,sun8i-h3-ths", .data = &sun8i_ths_h3_desc },
|
||||
+ { .compatible = "allwinner,sun8i-a83t-ths", .data = &sun8i_ths_a83t_desc },
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sun8i_ths_id_table);
|
||||
@@ -235,5 +412,5 @@ static struct platform_driver sun8i_ths_driver = {
|
||||
module_platform_driver(sun8i_ths_driver);
|
||||
|
||||
MODULE_AUTHOR("Ondřej Jirman <megous@megous.com>");
|
||||
-MODULE_DESCRIPTION("Thermal sensor driver for Allwinner H3 SoC");
|
||||
+MODULE_DESCRIPTION("Thermal sensor driver for Allwinner SUN8I SoCs");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
From 4e3d17aa91541ce9ad705432e6ef353efabeb06e Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Sat, 25 Jun 2016 00:02:04 +0200
|
||||
Subject: [PATCH 06/82] dt-bindings: document sun8i_ths - H3 thermal sensor
|
||||
driver
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This patch adds the binding documentation for the
|
||||
sun8i_ths driver. This is a driver for thermal sensor
|
||||
found in Allwinner H3 SoC.
|
||||
|
||||
Signed-off-by: Ondřej Jirman <megous@megous.com>
|
||||
---
|
||||
.../devicetree/bindings/thermal/sun8i-ths.txt | 24 +++++++++++++++++++
|
||||
1 file changed, 24 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/thermal/sun8i-ths.txt
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/thermal/sun8i-ths.txt b/Documentation/devicetree/bindings/thermal/sun8i-ths.txt
|
||||
new file mode 100644
|
||||
index 000000000000..ba1288165e90
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/thermal/sun8i-ths.txt
|
||||
@@ -0,0 +1,24 @@
|
||||
+* Thermal sensor driver for Allwinner H3 SoC
|
||||
+
|
||||
+Required properties:
|
||||
+- compatible : "allwinner,sun8i-h3-ths"
|
||||
+- reg : Address range of the thermal sensor registers
|
||||
+- resets : Must contain phandles to reset controls matching the entries
|
||||
+ of the names
|
||||
+- reset-names : Must include the name "ahb"
|
||||
+- clocks : Must contain phandles to clock controls matching the entries
|
||||
+ of the names
|
||||
+- clock-names : Must contain "ahb" for the bus gate and "ths" for the THS
|
||||
+ clock
|
||||
+
|
||||
+Example:
|
||||
+ths: ths@01c25000 {
|
||||
+ #thermal-sensor-cells = <0>;
|
||||
+ compatible = "allwinner,sun8i-h3-ths";
|
||||
+ reg = <0x01c25000 0x400>;
|
||||
+ interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ resets = <&bus_rst 136>;
|
||||
+ reset-names = "ahb";
|
||||
+ clocks = <&bus_gates 72>, <&ths_clk>;
|
||||
+ clock-names = "ahb", "ths";
|
||||
+};
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
From af866a2756362500a2e7a4d0cf600e266b5f5c4c Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Sun, 26 Feb 2017 16:05:58 +0100
|
||||
Subject: [PATCH 07/82] ARM: dts: sunxi-h3-h5: Add thermal sensor node to H3/H5
|
||||
|
||||
Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
---
|
||||
arch/arm/boot/dts/sunxi-h3-h5.dtsi | 21 +++++++++++++++++++++
|
||||
1 file changed, 21 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
|
||||
index fc6131315c47..13fe5e316136 100644
|
||||
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
|
||||
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
|
||||
@@ -488,6 +488,19 @@
|
||||
};
|
||||
};
|
||||
|
||||
+ ths: ths@1c25000 {
|
||||
+ #thermal-sensor-cells = <0>;
|
||||
+ compatible = "allwinner,sun8i-h3-ths";
|
||||
+ reg = <0x01c25000 0x400>,
|
||||
+ <0x01c14234 0x4>;
|
||||
+ reg-names = "ths", "calibration";
|
||||
+ interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ resets = <&ccu RST_BUS_THS>;
|
||||
+ reset-names = "ahb";
|
||||
+ clocks = <&ccu CLK_BUS_THS>, <&ccu CLK_THS>;
|
||||
+ clock-names = "ahb", "ths";
|
||||
+ };
|
||||
+
|
||||
timer@1c20c00 {
|
||||
compatible = "allwinner,sun4i-a10-timer";
|
||||
reg = <0x01c20c00 0xa0>;
|
||||
@@ -855,4 +868,12 @@
|
||||
};
|
||||
};
|
||||
};
|
||||
+
|
||||
+ thermal-zones {
|
||||
+ cpu_thermal: cpu_thermal {
|
||||
+ polling-delay-passive = <330>;
|
||||
+ polling-delay = <1000>;
|
||||
+ thermal-sensors = <&ths 0>;
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
From 1d78fb6bf60b011bd60ebc9d6ef9499f91c29267 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Thu, 30 Mar 2017 12:58:43 +0200
|
||||
Subject: [PATCH 08/82] cpufreq: dt-platdev: Add allwinner,sun50i-h5 compatible
|
||||
|
||||
---
|
||||
drivers/cpufreq/cpufreq-dt-platdev.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c
|
||||
index fe14c57de6ca..afb511aa5050 100644
|
||||
--- a/drivers/cpufreq/cpufreq-dt-platdev.c
|
||||
+++ b/drivers/cpufreq/cpufreq-dt-platdev.c
|
||||
@@ -29,6 +29,7 @@ static const struct of_device_id whitelist[] __initconst = {
|
||||
{ .compatible = "allwinner,sun8i-a23", },
|
||||
{ .compatible = "allwinner,sun8i-a83t", },
|
||||
{ .compatible = "allwinner,sun8i-h3", },
|
||||
+ { .compatible = "allwinner,sun50i-h5", },
|
||||
|
||||
{ .compatible = "apm,xgene-shadowcat", },
|
||||
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
From 3ef8fd9d164316d26eb99afec111e0431c2f2c69 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Sun, 13 May 2018 21:00:43 +0200
|
||||
Subject: [PATCH 09/82] ARM: dts: sun8i: Increase max CPUX voltage to 1.4V on
|
||||
Orange Pi PC
|
||||
|
||||
When using thermal regulation we can afford to go higher. Also add
|
||||
regulator-ramp-delay, because regulator takes some time to change
|
||||
voltage.
|
||||
|
||||
Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
---
|
||||
arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts b/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts
|
||||
index 46240334128f..83f1866ed9e7 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts
|
||||
@@ -204,7 +204,8 @@
|
||||
* Use 1.0V as the minimum voltage instead.
|
||||
*/
|
||||
regulator-min-microvolt = <1000000>;
|
||||
- regulator-max-microvolt = <1300000>;
|
||||
+ regulator-max-microvolt = <1400000>;
|
||||
+ regulator-ramp-delay = <200>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
From 0d1194aaf2b2ebc571cf01d2353d252c12146d2e Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Mon, 27 Jun 2016 16:08:26 +0200
|
||||
Subject: [PATCH 10/82] ARM: dts: sun8i-h3: Add clock-frequency
|
||||
|
||||
To avoid error messages during boot.
|
||||
|
||||
Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
---
|
||||
arch/arm/boot/dts/sun8i-h3.dtsi | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi
|
||||
index f0096074a467..cb19ff797606 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-h3.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun8i-h3.dtsi
|
||||
@@ -78,6 +78,7 @@
|
||||
clock-names = "cpu";
|
||||
operating-points-v2 = <&cpu0_opp_table>;
|
||||
#cooling-cells = <2>;
|
||||
+ clock-frequency = <1200000000>;
|
||||
};
|
||||
|
||||
cpu@1 {
|
||||
@@ -88,6 +89,7 @@
|
||||
clock-names = "cpu";
|
||||
operating-points-v2 = <&cpu0_opp_table>;
|
||||
#cooling-cells = <2>;
|
||||
+ clock-frequency = <1200000000>;
|
||||
};
|
||||
|
||||
cpu@2 {
|
||||
@@ -98,6 +100,7 @@
|
||||
clock-names = "cpu";
|
||||
operating-points-v2 = <&cpu0_opp_table>;
|
||||
#cooling-cells = <2>;
|
||||
+ clock-frequency = <1200000000>;
|
||||
};
|
||||
|
||||
cpu@3 {
|
||||
@@ -108,6 +111,7 @@
|
||||
clock-names = "cpu";
|
||||
operating-points-v2 = <&cpu0_opp_table>;
|
||||
#cooling-cells = <2>;
|
||||
+ clock-frequency = <1200000000>;
|
||||
};
|
||||
};
|
||||
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
From 6328da39df61f962190870089aaa171a7f8aab2c Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Thu, 30 Mar 2017 13:04:25 +0200
|
||||
Subject: [PATCH 11/82] arm64: dts: sun50i-h5: Add clock-frequency
|
||||
|
||||
To avoid error messages during boot.
|
||||
|
||||
Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
---
|
||||
arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
|
||||
index 62d646baac3c..4452ab873dec 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
|
||||
@@ -52,6 +52,7 @@
|
||||
device_type = "cpu";
|
||||
reg = <0>;
|
||||
enable-method = "psci";
|
||||
+ clock-frequency = <1200000000>;
|
||||
};
|
||||
|
||||
cpu@1 {
|
||||
@@ -59,6 +60,7 @@
|
||||
device_type = "cpu";
|
||||
reg = <1>;
|
||||
enable-method = "psci";
|
||||
+ clock-frequency = <1200000000>;
|
||||
};
|
||||
|
||||
cpu@2 {
|
||||
@@ -66,6 +68,7 @@
|
||||
device_type = "cpu";
|
||||
reg = <2>;
|
||||
enable-method = "psci";
|
||||
+ clock-frequency = <1200000000>;
|
||||
};
|
||||
|
||||
cpu@3 {
|
||||
@@ -73,6 +76,7 @@
|
||||
device_type = "cpu";
|
||||
reg = <3>;
|
||||
enable-method = "psci";
|
||||
+ clock-frequency = <1200000000>;
|
||||
};
|
||||
};
|
||||
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
From d4028daf51824eb792fb3c9cc77553ff1edc5d68 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Mon, 14 May 2018 00:56:50 +0200
|
||||
Subject: [PATCH 12/82] ARM: dts: sunxi-h3-h5: Move CPU OPP table to dtsi
|
||||
shared by H3/H5
|
||||
|
||||
It is identical for H3 and H5, so it better live there.
|
||||
|
||||
Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
---
|
||||
arch/arm/boot/dts/sun8i-h3.dtsi | 23 -----------------------
|
||||
arch/arm/boot/dts/sunxi-h3-h5.dtsi | 23 +++++++++++++++++++++++
|
||||
2 files changed, 23 insertions(+), 23 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi
|
||||
index cb19ff797606..261ca0356358 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-h3.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun8i-h3.dtsi
|
||||
@@ -43,29 +43,6 @@
|
||||
#include "sunxi-h3-h5.dtsi"
|
||||
|
||||
/ {
|
||||
- cpu0_opp_table: opp_table0 {
|
||||
- compatible = "operating-points-v2";
|
||||
- opp-shared;
|
||||
-
|
||||
- opp-648000000 {
|
||||
- opp-hz = /bits/ 64 <648000000>;
|
||||
- opp-microvolt = <1040000 1040000 1300000>;
|
||||
- clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
- };
|
||||
-
|
||||
- opp-816000000 {
|
||||
- opp-hz = /bits/ 64 <816000000>;
|
||||
- opp-microvolt = <1100000 1100000 1300000>;
|
||||
- clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
- };
|
||||
-
|
||||
- opp-1008000000 {
|
||||
- opp-hz = /bits/ 64 <1008000000>;
|
||||
- opp-microvolt = <1200000 1200000 1300000>;
|
||||
- clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
- };
|
||||
- };
|
||||
-
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
|
||||
index 13fe5e316136..539b69fecbe9 100644
|
||||
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
|
||||
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
|
||||
@@ -105,6 +105,29 @@
|
||||
};
|
||||
};
|
||||
|
||||
+ cpu0_opp_table: opp_table0 {
|
||||
+ compatible = "operating-points-v2";
|
||||
+ opp-shared;
|
||||
+
|
||||
+ opp@648000000 {
|
||||
+ opp-hz = /bits/ 64 <648000000>;
|
||||
+ opp-microvolt = <1040000 1040000 1300000>;
|
||||
+ clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
+ };
|
||||
+
|
||||
+ opp@816000000 {
|
||||
+ opp-hz = /bits/ 64 <816000000>;
|
||||
+ opp-microvolt = <1100000 1100000 1300000>;
|
||||
+ clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
+ };
|
||||
+
|
||||
+ opp@1008000000 {
|
||||
+ opp-hz = /bits/ 64 <1008000000>;
|
||||
+ opp-microvolt = <1200000 1200000 1300000>;
|
||||
+ clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
de: display-engine {
|
||||
compatible = "allwinner,sun8i-h3-display-engine";
|
||||
allwinner,pipelines = <&mixer0>;
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,116 +0,0 @@
|
|||
From 9e05f3d014b05df39a55dfd6a08d4bd18a301307 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Mon, 14 May 2018 01:13:01 +0200
|
||||
Subject: [PATCH 13/82] ARM: dts: sunxi-h3-h5: Add more CPU OPP for H3/H5
|
||||
|
||||
These OPPs can be used with better cooling and/or thermal regulation.
|
||||
|
||||
Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
---
|
||||
arch/arm/boot/dts/sunxi-h3-h5.dtsi | 78 ++++++++++++++++++++++++++++++
|
||||
1 file changed, 78 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
|
||||
index 539b69fecbe9..f47c22b622f9 100644
|
||||
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
|
||||
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
|
||||
@@ -109,6 +109,24 @@
|
||||
compatible = "operating-points-v2";
|
||||
opp-shared;
|
||||
|
||||
+ opp@120000000 {
|
||||
+ opp-hz = /bits/ 64 <120000000>;
|
||||
+ opp-microvolt = <1040000 1040000 1300000>;
|
||||
+ clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
+ };
|
||||
+
|
||||
+ opp@240000000 {
|
||||
+ opp-hz = /bits/ 64 <240000000>;
|
||||
+ opp-microvolt = <1040000 1040000 1300000>;
|
||||
+ clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
+ };
|
||||
+
|
||||
+ opp@480000000 {
|
||||
+ opp-hz = /bits/ 64 <480000000>;
|
||||
+ opp-microvolt = <1040000 1040000 1300000>;
|
||||
+ clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
+ };
|
||||
+
|
||||
opp@648000000 {
|
||||
opp-hz = /bits/ 64 <648000000>;
|
||||
opp-microvolt = <1040000 1040000 1300000>;
|
||||
@@ -121,11 +139,71 @@
|
||||
clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
};
|
||||
|
||||
+ opp@960000000 {
|
||||
+ opp-hz = /bits/ 64 <960000000>;
|
||||
+ opp-microvolt = <1200000 1200000 1300000>;
|
||||
+ clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
+ };
|
||||
+
|
||||
opp@1008000000 {
|
||||
opp-hz = /bits/ 64 <1008000000>;
|
||||
opp-microvolt = <1200000 1200000 1300000>;
|
||||
clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
};
|
||||
+
|
||||
+ opp@1056000000 {
|
||||
+ opp-hz = /bits/ 64 <1056000000>;
|
||||
+ opp-microvolt = <1320000 1320000 1320000>;
|
||||
+ clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
+ };
|
||||
+
|
||||
+ opp@1104000000 {
|
||||
+ opp-hz = /bits/ 64 <1104000000>;
|
||||
+ opp-microvolt = <1320000 1320000 1320000>;
|
||||
+ clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
+ };
|
||||
+
|
||||
+ opp@1152000000 {
|
||||
+ opp-hz = /bits/ 64 <1152000000>;
|
||||
+ opp-microvolt = <1320000 1320000 1320000>;
|
||||
+ clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
+ };
|
||||
+
|
||||
+ opp@1200000000 {
|
||||
+ opp-hz = /bits/ 64 <1200000000>;
|
||||
+ opp-microvolt = <1320000 1320000 1320000>;
|
||||
+ clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
+ };
|
||||
+
|
||||
+ opp@1224000000 {
|
||||
+ opp-hz = /bits/ 64 <1224000000>;
|
||||
+ opp-microvolt = <1340000 1340000 1340000>;
|
||||
+ clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
+ };
|
||||
+
|
||||
+ opp@1248000000 {
|
||||
+ opp-hz = /bits/ 64 <1248000000>;
|
||||
+ opp-microvolt = <1340000 1340000 1340000>;
|
||||
+ clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
+ };
|
||||
+
|
||||
+ opp@1296000000 {
|
||||
+ opp-hz = /bits/ 64 <1296000000>;
|
||||
+ opp-microvolt = <1340000 1340000 1340000>;
|
||||
+ clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
+ };
|
||||
+
|
||||
+ opp@1344000000 {
|
||||
+ opp-hz = /bits/ 64 <1344000000>;
|
||||
+ opp-microvolt = <1400000 1400000 1400000>;
|
||||
+ clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
+ };
|
||||
+
|
||||
+ opp@1368000000 {
|
||||
+ opp-hz = /bits/ 64 <1368000000>;
|
||||
+ opp-microvolt = <1400000 1400000 1400000>;
|
||||
+ clock-latency-ns = <244144>; /* 8 32k periods */
|
||||
+ };
|
||||
};
|
||||
|
||||
de: display-engine {
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,86 +0,0 @@
|
|||
From 6914945e888f1206df560ff36375e7257ce38970 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Mon, 14 May 2018 01:16:06 +0200
|
||||
Subject: [PATCH 14/82] ARM: dts: sunxi-h3-h5: Add thermal zone trip points
|
||||
|
||||
This enables passive cooling by downregulating CPU voltage/frequency.
|
||||
|
||||
Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
---
|
||||
arch/arm/boot/dts/sun8i-h3.dtsi | 4 +++-
|
||||
arch/arm/boot/dts/sunxi-h3-h5.dtsi | 21 ++++++++++++++++++++
|
||||
arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi | 3 +++
|
||||
3 files changed, 27 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi
|
||||
index 261ca0356358..af76a6d250b3 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-h3.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun8i-h3.dtsi
|
||||
@@ -54,8 +54,10 @@
|
||||
clocks = <&ccu CLK_CPUX>;
|
||||
clock-names = "cpu";
|
||||
operating-points-v2 = <&cpu0_opp_table>;
|
||||
- #cooling-cells = <2>;
|
||||
clock-frequency = <1200000000>;
|
||||
+ #cooling-cells = <2>;
|
||||
+ cooling-min-level = <0>;
|
||||
+ cooling-max-level = <15>;
|
||||
};
|
||||
|
||||
cpu@1 {
|
||||
diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
|
||||
index f47c22b622f9..3b8b2234ab4d 100644
|
||||
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
|
||||
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
|
||||
@@ -47,6 +47,7 @@
|
||||
#include <dt-bindings/reset/sun8i-de2.h>
|
||||
#include <dt-bindings/reset/sun8i-h3-ccu.h>
|
||||
#include <dt-bindings/reset/sun8i-r-ccu.h>
|
||||
+#include <dt-bindings/thermal/thermal.h>
|
||||
|
||||
/ {
|
||||
interrupt-parent = <&gic>;
|
||||
@@ -975,6 +976,26 @@
|
||||
polling-delay-passive = <330>;
|
||||
polling-delay = <1000>;
|
||||
thermal-sensors = <&ths 0>;
|
||||
+
|
||||
+ trips {
|
||||
+ cpu_hot_trip: cpu-warm {
|
||||
+ temperature = <65000>;
|
||||
+ hysteresis = <2000>;
|
||||
+ type = "passive";
|
||||
+ };
|
||||
+ cpu_very_hot_trip: cpu-very-hot {
|
||||
+ temperature = <90000>;
|
||||
+ hysteresis = <2000>;
|
||||
+ type = "critical";
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ cooling-maps {
|
||||
+ cpu-warm-limit {
|
||||
+ trip = <&cpu_hot_trip>;
|
||||
+ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
};
|
||||
};
|
||||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
|
||||
index 4452ab873dec..60fc84a1fb44 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
|
||||
@@ -53,6 +53,9 @@
|
||||
reg = <0>;
|
||||
enable-method = "psci";
|
||||
clock-frequency = <1200000000>;
|
||||
+ #cooling-cells = <2>;
|
||||
+ cooling-min-level = <0>;
|
||||
+ cooling-max-level = <15>;
|
||||
};
|
||||
|
||||
cpu@1 {
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
From 25be6ff78bebfd869a3be0017715f101bd75bb64 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Mon, 14 May 2018 01:19:06 +0200
|
||||
Subject: [PATCH 15/82] arm64: dts: sun50i-h5: Enable cpufreq-dt on H5 CPU
|
||||
|
||||
Uses OPPs shared with H3.
|
||||
|
||||
Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
---
|
||||
arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
|
||||
index 60fc84a1fb44..acd90f390e88 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
|
||||
@@ -52,6 +52,9 @@
|
||||
device_type = "cpu";
|
||||
reg = <0>;
|
||||
enable-method = "psci";
|
||||
+ clocks = <&ccu CLK_CPUX>;
|
||||
+ clock-names = "cpu";
|
||||
+ operating-points-v2 = <&cpu0_opp_table>;
|
||||
clock-frequency = <1200000000>;
|
||||
#cooling-cells = <2>;
|
||||
cooling-min-level = <0>;
|
||||
@@ -63,6 +66,7 @@
|
||||
device_type = "cpu";
|
||||
reg = <1>;
|
||||
enable-method = "psci";
|
||||
+ operating-points-v2 = <&cpu0_opp_table>;
|
||||
clock-frequency = <1200000000>;
|
||||
};
|
||||
|
||||
@@ -71,6 +75,7 @@
|
||||
device_type = "cpu";
|
||||
reg = <2>;
|
||||
enable-method = "psci";
|
||||
+ operating-points-v2 = <&cpu0_opp_table>;
|
||||
clock-frequency = <1200000000>;
|
||||
};
|
||||
|
||||
@@ -79,6 +84,7 @@
|
||||
device_type = "cpu";
|
||||
reg = <3>;
|
||||
enable-method = "psci";
|
||||
+ operating-points-v2 = <&cpu0_opp_table>;
|
||||
clock-frequency = <1200000000>;
|
||||
};
|
||||
};
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
From 2f3ebd02a475c51f0ee4ac20fd9462f7f8cad314 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Thu, 30 Mar 2017 13:01:10 +0200
|
||||
Subject: [PATCH 16/82] arm64: dts: sun50i-h5-orange-pi-pc2: Setup CPUX voltage
|
||||
regulator
|
||||
|
||||
Orange Pi PC2 features sy8106a regulator just like Orange Pi PC.
|
||||
|
||||
Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
---
|
||||
.../dts/allwinner/sun50i-h5-orangepi-pc2.dts | 29 +++++++++++++++++++
|
||||
1 file changed, 29 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts
|
||||
index 3e0d5a9c096d..af8e3fe26e20 100644
|
||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts
|
||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts
|
||||
@@ -124,6 +124,10 @@
|
||||
};
|
||||
};
|
||||
|
||||
+&cpu0 {
|
||||
+ cpu-supply = <®_vdd_cpux>;
|
||||
+};
|
||||
+
|
||||
&codec {
|
||||
allwinner,audio-routing =
|
||||
"Line Out", "LINEOUT",
|
||||
@@ -219,6 +223,31 @@
|
||||
};
|
||||
};
|
||||
|
||||
+&r_i2c {
|
||||
+ status = "okay";
|
||||
+
|
||||
+ reg_vdd_cpux: regulator@65 {
|
||||
+ compatible = "silergy,sy8106a";
|
||||
+ reg = <0x65>;
|
||||
+ regulator-name = "vdd-cpux";
|
||||
+ silergy,fixed-microvolt = <1200000>;
|
||||
+ /*
|
||||
+ * The datasheet uses 1.1V as the minimum value of VDD-CPUX,
|
||||
+ * however both the Armbian DVFS table and the official one
|
||||
+ * have operating points with voltage under 1.1V, and both
|
||||
+ * DVFS table are known to work properly at the lowest
|
||||
+ * operating point.
|
||||
+ *
|
||||
+ * Use 1.0V as the minimum voltage instead.
|
||||
+ */
|
||||
+ regulator-min-microvolt = <1000000>;
|
||||
+ regulator-max-microvolt = <1400000>;
|
||||
+ regulator-ramp-delay = <200>;
|
||||
+ regulator-boot-on;
|
||||
+ regulator-always-on;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
&uart0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&uart0_pins_a>;
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,127 +0,0 @@
|
|||
From 997e53ee52efc4a0602bf298125a7c9758abf15c Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Myl=C3=A8ne=20Josserand?= <mylene.josserand@bootlin.com>
|
||||
Date: Wed, 25 Jul 2018 09:34:08 +0200
|
||||
Subject: [PATCH 17/82] Input: edt-ft5x06 - Add support for regulator
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Add the support of regulator to use it as VCC source.
|
||||
|
||||
Signed-off-by: Mylène Josserand <mylene.josserand@bootlin.com>
|
||||
Reviewed-by: Rob Herring <robh@kernel.org>
|
||||
---
|
||||
.../bindings/input/touchscreen/edt-ft5x06.txt | 1 +
|
||||
drivers/input/touchscreen/edt-ft5x06.c | 43 +++++++++++++++++++
|
||||
2 files changed, 44 insertions(+)
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt b/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt
|
||||
index da2dc5d6c98b..987faeb2fe4a 100644
|
||||
--- a/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt
|
||||
+++ b/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt
|
||||
@@ -28,6 +28,7 @@ Required properties:
|
||||
Optional properties:
|
||||
- reset-gpios: GPIO specification for the RESET input
|
||||
- wake-gpios: GPIO specification for the WAKE input
|
||||
+ - vcc-supply: Regulator that supplies the touchscreen
|
||||
|
||||
- pinctrl-names: should be "default"
|
||||
- pinctrl-0: a phandle pointing to the pin settings for the
|
||||
diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
|
||||
index 1e18ca0d1b4e..dcde719094f7 100644
|
||||
--- a/drivers/input/touchscreen/edt-ft5x06.c
|
||||
+++ b/drivers/input/touchscreen/edt-ft5x06.c
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <linux/input/mt.h>
|
||||
#include <linux/input/touchscreen.h>
|
||||
#include <linux/of_device.h>
|
||||
+#include <linux/regulator/consumer.h>
|
||||
|
||||
#define WORK_REGISTER_THRESHOLD 0x00
|
||||
#define WORK_REGISTER_REPORT_RATE 0x08
|
||||
@@ -91,6 +92,7 @@ struct edt_ft5x06_ts_data {
|
||||
struct touchscreen_properties prop;
|
||||
u16 num_x;
|
||||
u16 num_y;
|
||||
+ struct regulator *vcc;
|
||||
|
||||
struct gpio_desc *reset_gpio;
|
||||
struct gpio_desc *wake_gpio;
|
||||
@@ -963,6 +965,13 @@ edt_ft5x06_ts_set_regs(struct edt_ft5x06_ts_data *tsdata)
|
||||
}
|
||||
}
|
||||
|
||||
+static void edt_ft5x06_disable_regulator(void *arg)
|
||||
+{
|
||||
+ struct edt_ft5x06_ts_data *data = arg;
|
||||
+
|
||||
+ regulator_disable(data->vcc);
|
||||
+}
|
||||
+
|
||||
static int edt_ft5x06_ts_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
@@ -991,6 +1000,28 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
|
||||
|
||||
tsdata->max_support_points = chip_data->max_support_points;
|
||||
|
||||
+ tsdata->vcc = devm_regulator_get(&client->dev, "vcc");
|
||||
+ if (IS_ERR(tsdata->vcc)) {
|
||||
+ error = PTR_ERR(tsdata->vcc);
|
||||
+ if (error != -EPROBE_DEFER)
|
||||
+ dev_err(&client->dev, "failed to request regulator: %d\n",
|
||||
+ error);
|
||||
+ return error;
|
||||
+ }
|
||||
+
|
||||
+ error = regulator_enable(tsdata->vcc);
|
||||
+ if (error < 0) {
|
||||
+ dev_err(&client->dev, "failed to enable vcc: %d\n",
|
||||
+ error);
|
||||
+ return error;
|
||||
+ }
|
||||
+
|
||||
+ error = devm_add_action_or_reset(&client->dev,
|
||||
+ edt_ft5x06_disable_regulator,
|
||||
+ tsdata);
|
||||
+ if (error)
|
||||
+ return error;
|
||||
+
|
||||
tsdata->reset_gpio = devm_gpiod_get_optional(&client->dev,
|
||||
"reset", GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(tsdata->reset_gpio)) {
|
||||
@@ -1120,9 +1151,12 @@ static int edt_ft5x06_ts_remove(struct i2c_client *client)
|
||||
static int __maybe_unused edt_ft5x06_ts_suspend(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
+ struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
|
||||
|
||||
if (device_may_wakeup(dev))
|
||||
enable_irq_wake(client->irq);
|
||||
+ else
|
||||
+ regulator_disable(tsdata->vcc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1130,9 +1164,18 @@ static int __maybe_unused edt_ft5x06_ts_suspend(struct device *dev)
|
||||
static int __maybe_unused edt_ft5x06_ts_resume(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
+ struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
|
||||
+ int ret;
|
||||
|
||||
if (device_may_wakeup(dev))
|
||||
disable_irq_wake(client->irq);
|
||||
+ else {
|
||||
+ ret = regulator_enable(tsdata->vcc);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(dev, "failed to enable vcc: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
return 0;
|
||||
}
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
From 6ff7153330ff8a6c3427e6445e5015620d687c81 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Myl=C3=A8ne=20Josserand?= <mylene.josserand@bootlin.com>
|
||||
Date: Wed, 25 Jul 2018 09:34:09 +0200
|
||||
Subject: [PATCH 18/82] Input: edt-ft5x06 - Set wake/reset values on
|
||||
resume/suspend
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
On resume and suspend, set the value of wake and reset gpios
|
||||
to be sure that we are in a know state after suspending/resuming.
|
||||
|
||||
Signed-off-by: Mylène Josserand <mylene.josserand@bootlin.com>
|
||||
---
|
||||
drivers/input/touchscreen/edt-ft5x06.c | 12 ++++++++++++
|
||||
1 file changed, 12 insertions(+)
|
||||
|
||||
diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
|
||||
index dcde719094f7..dad2f1f8bf89 100644
|
||||
--- a/drivers/input/touchscreen/edt-ft5x06.c
|
||||
+++ b/drivers/input/touchscreen/edt-ft5x06.c
|
||||
@@ -1158,6 +1158,12 @@ static int __maybe_unused edt_ft5x06_ts_suspend(struct device *dev)
|
||||
else
|
||||
regulator_disable(tsdata->vcc);
|
||||
|
||||
+ if (tsdata->wake_gpio)
|
||||
+ gpiod_set_value(tsdata->wake_gpio, 0);
|
||||
+
|
||||
+ if (tsdata->reset_gpio)
|
||||
+ gpiod_set_value(tsdata->reset_gpio, 1);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1177,6 +1183,12 @@ static int __maybe_unused edt_ft5x06_ts_resume(struct device *dev)
|
||||
}
|
||||
}
|
||||
|
||||
+ if (tsdata->wake_gpio)
|
||||
+ gpiod_set_value(tsdata->wake_gpio, 1);
|
||||
+
|
||||
+ if (tsdata->reset_gpio)
|
||||
+ gpiod_set_value(tsdata->reset_gpio, 0);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
From 0e03253586345216dfb55cdd9b8f038023e0d9bc Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Myl=C3=A8ne=20Josserand?= <mylene.josserand@bootlin.com>
|
||||
Date: Wed, 25 Jul 2018 09:34:10 +0200
|
||||
Subject: [PATCH 19/82] arm: dts: sun8i: a83t: a711: Add touchscreen node
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Tha A711 tablet has a FocalTech EDT-FT5x06 Polytouch touchscreen.
|
||||
It is connected via I2C0. The reset line is PD5, the interrupt
|
||||
line is PL7 and the VCC supply is the ldo_io0 regulator.
|
||||
|
||||
Signed-off-by: Mylène Josserand <mylene.josserand@bootlin.com>
|
||||
---
|
||||
arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 16 ++++++++++++++++
|
||||
1 file changed, 16 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
index 1537ce148cc1..dc7b94a6c068 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
@@ -156,6 +156,22 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+&i2c0 {
|
||||
+ clock-frequency = <400000>;
|
||||
+ status = "okay";
|
||||
+
|
||||
+ touchscreen@38 {
|
||||
+ compatible = "edt,edt-ft5x06";
|
||||
+ reg = <0x38>;
|
||||
+ interrupt-parent = <&r_pio>;
|
||||
+ interrupts = <0 7 IRQ_TYPE_EDGE_FALLING>;
|
||||
+ reset-gpios = <&pio 3 5 GPIO_ACTIVE_LOW>;
|
||||
+ vcc-supply = <®_ldo_io0>;
|
||||
+ touchscreen-size-x = <1024>;
|
||||
+ touchscreen-size-y = <600>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
&mmc0 {
|
||||
vmmc-supply = <®_dcdc1>;
|
||||
pinctrl-names = "default";
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,86 +0,0 @@
|
|||
From 84a6ce439660f26a06219cdf1613f87a6395fdbd Mon Sep 17 00:00:00 2001
|
||||
From: Quentin Schulz <quentin.schulz@free-electrons.com>
|
||||
Date: Wed, 23 Aug 2017 14:15:59 +0200
|
||||
Subject: [PATCH 20/82] power: supply: axp20x_usb_power: add function to get
|
||||
max current
|
||||
|
||||
To prepare for a new PMIC, factor out the code responsible of returning
|
||||
the maximum current to axp20x_get_current_max.
|
||||
|
||||
Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>
|
||||
---
|
||||
drivers/power/supply/axp20x_usb_power.c | 51 ++++++++++++++-----------
|
||||
1 file changed, 29 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/drivers/power/supply/axp20x_usb_power.c b/drivers/power/supply/axp20x_usb_power.c
|
||||
index 42001df4bd13..464d4abd3798 100644
|
||||
--- a/drivers/power/supply/axp20x_usb_power.c
|
||||
+++ b/drivers/power/supply/axp20x_usb_power.c
|
||||
@@ -63,6 +63,34 @@ static irqreturn_t axp20x_usb_power_irq(int irq, void *devid)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
+static int axp20x_get_current_max(struct axp20x_usb_power *power, int *val)
|
||||
+{
|
||||
+ unsigned int v;
|
||||
+ int ret = regmap_read(power->regmap, AXP20X_VBUS_IPSOUT_MGMT, &v);
|
||||
+
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ switch (v & AXP20X_VBUS_CLIMIT_MASK) {
|
||||
+ case AXP20X_VBUC_CLIMIT_100mA:
|
||||
+ if (power->axp20x_id == AXP221_ID)
|
||||
+ *val = -1; /* No 100mA limit */
|
||||
+ else
|
||||
+ *val = 100000;
|
||||
+ break;
|
||||
+ case AXP20X_VBUC_CLIMIT_500mA:
|
||||
+ *val = 500000;
|
||||
+ break;
|
||||
+ case AXP20X_VBUC_CLIMIT_900mA:
|
||||
+ *val = 900000;
|
||||
+ break;
|
||||
+ case AXP20X_VBUC_CLIMIT_NONE:
|
||||
+ *val = -1;
|
||||
+ break;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int axp20x_usb_power_get_property(struct power_supply *psy,
|
||||
enum power_supply_property psp, union power_supply_propval *val)
|
||||
{
|
||||
@@ -101,28 +129,7 @@ static int axp20x_usb_power_get_property(struct power_supply *psy,
|
||||
val->intval = ret * 1700; /* 1 step = 1.7 mV */
|
||||
return 0;
|
||||
case POWER_SUPPLY_PROP_CURRENT_MAX:
|
||||
- ret = regmap_read(power->regmap, AXP20X_VBUS_IPSOUT_MGMT, &v);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- switch (v & AXP20X_VBUS_CLIMIT_MASK) {
|
||||
- case AXP20X_VBUC_CLIMIT_100mA:
|
||||
- if (power->axp20x_id == AXP221_ID)
|
||||
- val->intval = -1; /* No 100mA limit */
|
||||
- else
|
||||
- val->intval = 100000;
|
||||
- break;
|
||||
- case AXP20X_VBUC_CLIMIT_500mA:
|
||||
- val->intval = 500000;
|
||||
- break;
|
||||
- case AXP20X_VBUC_CLIMIT_900mA:
|
||||
- val->intval = 900000;
|
||||
- break;
|
||||
- case AXP20X_VBUC_CLIMIT_NONE:
|
||||
- val->intval = -1;
|
||||
- break;
|
||||
- }
|
||||
- return 0;
|
||||
+ return axp20x_get_current_max(power, &val->intval);
|
||||
case POWER_SUPPLY_PROP_CURRENT_NOW:
|
||||
if (IS_ENABLED(CONFIG_AXP20X_ADC)) {
|
||||
ret = iio_read_channel_processed(power->vbus_i,
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,135 +0,0 @@
|
|||
From 5c2f08f5428ed5239b5e90a308e2f77cbc8238b0 Mon Sep 17 00:00:00 2001
|
||||
From: Quentin Schulz <quentin.schulz@free-electrons.com>
|
||||
Date: Wed, 23 Aug 2017 15:03:42 +0200
|
||||
Subject: [PATCH 21/82] power: supply: axp20x_usb_power: add support for AXP813
|
||||
|
||||
This adds support for AXP813 PMIC. It is almost the same as AXP22X but
|
||||
has a different current limit.
|
||||
|
||||
Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>
|
||||
---
|
||||
drivers/power/supply/axp20x_usb_power.c | 66 ++++++++++++++++++++++++-
|
||||
1 file changed, 65 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/power/supply/axp20x_usb_power.c b/drivers/power/supply/axp20x_usb_power.c
|
||||
index 464d4abd3798..4b04fb8f496c 100644
|
||||
--- a/drivers/power/supply/axp20x_usb_power.c
|
||||
+++ b/drivers/power/supply/axp20x_usb_power.c
|
||||
@@ -40,6 +40,11 @@
|
||||
#define AXP20X_VBUC_CLIMIT_100mA 2
|
||||
#define AXP20X_VBUC_CLIMIT_NONE 3
|
||||
|
||||
+#define AXP813_VBUC_CLIMIT_900mA 0
|
||||
+#define AXP813_VBUC_CLIMIT_1500mA 1
|
||||
+#define AXP813_VBUC_CLIMIT_2000mA 2
|
||||
+#define AXP813_VBUC_CLIMIT_2500mA 3
|
||||
+
|
||||
#define AXP20X_ADC_EN1_VBUS_CURR BIT(2)
|
||||
#define AXP20X_ADC_EN1_VBUS_VOLT BIT(3)
|
||||
|
||||
@@ -63,6 +68,31 @@ static irqreturn_t axp20x_usb_power_irq(int irq, void *devid)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
+static int axp813_get_current_max(struct axp20x_usb_power *power, int *val)
|
||||
+{
|
||||
+ unsigned int v;
|
||||
+ int ret = regmap_read(power->regmap, AXP20X_VBUS_IPSOUT_MGMT, &v);
|
||||
+
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ switch (v & AXP20X_VBUS_CLIMIT_MASK) {
|
||||
+ case AXP813_VBUC_CLIMIT_900mA:
|
||||
+ *val = 900000;
|
||||
+ break;
|
||||
+ case AXP813_VBUC_CLIMIT_1500mA:
|
||||
+ *val = 1500000;
|
||||
+ break;
|
||||
+ case AXP813_VBUC_CLIMIT_2000mA:
|
||||
+ *val = 2000000;
|
||||
+ break;
|
||||
+ case AXP813_VBUC_CLIMIT_2500mA:
|
||||
+ *val = 2500000;
|
||||
+ break;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int axp20x_get_current_max(struct axp20x_usb_power *power, int *val)
|
||||
{
|
||||
unsigned int v;
|
||||
@@ -129,6 +159,8 @@ static int axp20x_usb_power_get_property(struct power_supply *psy,
|
||||
val->intval = ret * 1700; /* 1 step = 1.7 mV */
|
||||
return 0;
|
||||
case POWER_SUPPLY_PROP_CURRENT_MAX:
|
||||
+ if (power->axp20x_id == AXP813_ID)
|
||||
+ return axp813_get_current_max(power, &val->intval);
|
||||
return axp20x_get_current_max(power, &val->intval);
|
||||
case POWER_SUPPLY_PROP_CURRENT_NOW:
|
||||
if (IS_ENABLED(CONFIG_AXP20X_ADC)) {
|
||||
@@ -220,6 +252,31 @@ static int axp20x_usb_power_set_voltage_min(struct axp20x_usb_power *power,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
+static int axp813_usb_power_set_current_max(struct axp20x_usb_power *power,
|
||||
+ int intval)
|
||||
+{
|
||||
+ int val;
|
||||
+
|
||||
+ switch (intval) {
|
||||
+ case 900000:
|
||||
+ return regmap_update_bits(power->regmap,
|
||||
+ AXP20X_VBUS_IPSOUT_MGMT,
|
||||
+ AXP20X_VBUS_CLIMIT_MASK,
|
||||
+ AXP813_VBUC_CLIMIT_900mA);
|
||||
+ case 1500000:
|
||||
+ case 2000000:
|
||||
+ case 2500000:
|
||||
+ val = (intval - 1000000) / 500000;
|
||||
+ return regmap_update_bits(power->regmap,
|
||||
+ AXP20X_VBUS_IPSOUT_MGMT,
|
||||
+ AXP20X_VBUS_CLIMIT_MASK, val);
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return -EINVAL;
|
||||
+}
|
||||
+
|
||||
static int axp20x_usb_power_set_current_max(struct axp20x_usb_power *power,
|
||||
int intval)
|
||||
{
|
||||
@@ -254,6 +311,9 @@ static int axp20x_usb_power_set_property(struct power_supply *psy,
|
||||
return axp20x_usb_power_set_voltage_min(power, val->intval);
|
||||
|
||||
case POWER_SUPPLY_PROP_CURRENT_MAX:
|
||||
+ if (power->axp20x_id == AXP813_ID)
|
||||
+ return axp813_usb_power_set_current_max(power,
|
||||
+ val->intval);
|
||||
return axp20x_usb_power_set_current_max(power, val->intval);
|
||||
|
||||
default:
|
||||
@@ -388,7 +448,8 @@ static int axp20x_usb_power_probe(struct platform_device *pdev)
|
||||
usb_power_desc = &axp20x_usb_power_desc;
|
||||
irq_names = axp20x_irq_names;
|
||||
} else if (power->axp20x_id == AXP221_ID ||
|
||||
- power->axp20x_id == AXP223_ID) {
|
||||
+ power->axp20x_id == AXP223_ID ||
|
||||
+ power->axp20x_id == AXP813_ID) {
|
||||
usb_power_desc = &axp22x_usb_power_desc;
|
||||
irq_names = axp22x_irq_names;
|
||||
} else {
|
||||
@@ -434,6 +495,9 @@ static const struct of_device_id axp20x_usb_power_match[] = {
|
||||
}, {
|
||||
.compatible = "x-powers,axp223-usb-power-supply",
|
||||
.data = (void *)AXP223_ID,
|
||||
+ }, {
|
||||
+ .compatible = "x-powers,axp813-usb-power-supply",
|
||||
+ .data = (void *)AXP813_ID,
|
||||
}, { /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, axp20x_usb_power_match);
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
From 8d81c934be105c53309f66057cabaf5cb496aec7 Mon Sep 17 00:00:00 2001
|
||||
From: Quentin Schulz <quentin.schulz@free-electrons.com>
|
||||
Date: Wed, 23 Aug 2017 15:06:28 +0200
|
||||
Subject: [PATCH 22/82] ARM: dtsi: axp813: add USB power supply node
|
||||
|
||||
Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>
|
||||
---
|
||||
arch/arm/boot/dts/axp81x.dtsi | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/axp81x.dtsi b/arch/arm/boot/dts/axp81x.dtsi
|
||||
index 043c717dcef1..f32a8ba53b85 100644
|
||||
--- a/arch/arm/boot/dts/axp81x.dtsi
|
||||
+++ b/arch/arm/boot/dts/axp81x.dtsi
|
||||
@@ -166,4 +166,8 @@
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
+
|
||||
+ usb_power_supply: usb-power-supply {
|
||||
+ compatible = "x-powers,axp813-usb-power-supply";
|
||||
+ };
|
||||
};
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
From 95a44a737d3a50a67eabad266aeb7b8d763ef5d2 Mon Sep 17 00:00:00 2001
|
||||
From: Quentin Schulz <quentin.schulz@free-electrons.com>
|
||||
Date: Wed, 23 Aug 2017 15:07:14 +0200
|
||||
Subject: [PATCH 23/82] mfd: axp20x: add USB power supply mfd cell to AXP813
|
||||
|
||||
Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>
|
||||
---
|
||||
drivers/mfd/axp20x.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
|
||||
index f8e0fa97bb31..ac8da970bdfe 100644
|
||||
--- a/drivers/mfd/axp20x.c
|
||||
+++ b/drivers/mfd/axp20x.c
|
||||
@@ -787,6 +787,9 @@ static const struct mfd_cell axp813_cells[] = {
|
||||
}, {
|
||||
.name = "axp20x-battery-power-supply",
|
||||
.of_compatible = "x-powers,axp813-battery-power-supply",
|
||||
+ }, {
|
||||
+ .name = "axp20x-usb-power-supply",
|
||||
+ .of_compatible = "x-powers,axp813-usb-power-supply",
|
||||
}, {
|
||||
.name = "axp20x-ac-power-supply",
|
||||
.of_compatible = "x-powers,axp813-ac-power-supply",
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
From b77e60c6a2797ada240b1d42b896b70853e2b1af Mon Sep 17 00:00:00 2001
|
||||
From: Quentin Schulz <quentin.schulz@free-electrons.com>
|
||||
Date: Thu, 10 Aug 2017 09:40:21 +0200
|
||||
Subject: [PATCH 24/82] mfd: axp20x: add regulator-userspace-consumer to mfd
|
||||
cells of AXP813
|
||||
|
||||
Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>
|
||||
---
|
||||
drivers/mfd/axp20x.c | 15 +++++++++++++++
|
||||
1 file changed, 15 insertions(+)
|
||||
|
||||
diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
|
||||
index ac8da970bdfe..95f36a7e3cd4 100644
|
||||
--- a/drivers/mfd/axp20x.c
|
||||
+++ b/drivers/mfd/axp20x.c
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
+#include <linux/regulator/userspace-consumer.h>
|
||||
#include <linux/mfd/axp20x.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/of_device.h>
|
||||
@@ -771,6 +772,16 @@ static const struct mfd_cell axp809_cells[] = {
|
||||
},
|
||||
};
|
||||
|
||||
+static struct regulator_bulk_data vcc_vb = {
|
||||
+ .supply = "vcc-vb",
|
||||
+};
|
||||
+
|
||||
+static struct regulator_userspace_consumer_data vcc_vb_data = {
|
||||
+ .name = "vcc-vb",
|
||||
+ .num_supplies = 1,
|
||||
+ .supplies = &vcc_vb,
|
||||
+};
|
||||
+
|
||||
static const struct mfd_cell axp813_cells[] = {
|
||||
{
|
||||
.name = "axp221-pek",
|
||||
@@ -790,6 +801,10 @@ static const struct mfd_cell axp813_cells[] = {
|
||||
}, {
|
||||
.name = "axp20x-usb-power-supply",
|
||||
.of_compatible = "x-powers,axp813-usb-power-supply",
|
||||
+ }, {
|
||||
+ .name = "reg-userspace-consumer",
|
||||
+ .platform_data = &vcc_vb_data,
|
||||
+ .pdata_size = sizeof(vcc_vb_data),
|
||||
}, {
|
||||
.name = "axp20x-ac-power-supply",
|
||||
.of_compatible = "x-powers,axp813-ac-power-supply",
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,188 +0,0 @@
|
|||
From 49675ccdafd63d0eee2fb0a57bd39fcb07a83bae Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Tue, 14 Nov 2017 02:09:43 +0100
|
||||
Subject: [PATCH 25/82] power: supply: axp20x-usb-power: Support input current
|
||||
limit
|
||||
|
||||
Allow to set input current limit directly when autodetection fails
|
||||
on incorrectly wired tablets, like TBS A711, that don't have
|
||||
D+/D- pins connected, and can't detect the usb power supply type.
|
||||
|
||||
Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
---
|
||||
drivers/power/supply/axp20x_usb_power.c | 104 +++++++++++++++++++++++-
|
||||
include/linux/mfd/axp20x.h | 1 +
|
||||
2 files changed, 104 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/power/supply/axp20x_usb_power.c b/drivers/power/supply/axp20x_usb_power.c
|
||||
index 4b04fb8f496c..3bc2e1f7ab83 100644
|
||||
--- a/drivers/power/supply/axp20x_usb_power.c
|
||||
+++ b/drivers/power/supply/axp20x_usb_power.c
|
||||
@@ -49,6 +49,8 @@
|
||||
#define AXP20X_ADC_EN1_VBUS_VOLT BIT(3)
|
||||
|
||||
#define AXP20X_VBUS_MON_VBUS_VALID BIT(3)
|
||||
+#define AXP813_CHRG_CTRL3_VBUS_CUR_LIMIT_MASK GENMASK(7, 4)
|
||||
+#define AXP813_CHRG_CTRL3_VBUS_CUR_LIMIT_OFFSET 4
|
||||
|
||||
struct axp20x_usb_power {
|
||||
struct device_node *np;
|
||||
@@ -93,6 +95,50 @@ static int axp813_get_current_max(struct axp20x_usb_power *power, int *val)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int
|
||||
+axp813_usb_power_get_input_current_limit(struct axp20x_usb_power *power,
|
||||
+ int *intval)
|
||||
+{
|
||||
+ unsigned int v;
|
||||
+ int ret = regmap_read(power->regmap, AXP813_CHRG_CTRL3, &v);
|
||||
+
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ v &= AXP813_CHRG_CTRL3_VBUS_CUR_LIMIT_MASK;
|
||||
+ v >>= AXP813_CHRG_CTRL3_VBUS_CUR_LIMIT_OFFSET;
|
||||
+
|
||||
+ switch (v) {
|
||||
+ case 0:
|
||||
+ *intval = 100000;
|
||||
+ return 0;
|
||||
+ case 1:
|
||||
+ *intval = 500000;
|
||||
+ return 0;
|
||||
+ case 2:
|
||||
+ *intval = 900000;
|
||||
+ return 0;
|
||||
+ case 3:
|
||||
+ *intval = 1500000;
|
||||
+ return 0;
|
||||
+ case 4:
|
||||
+ *intval = 2000000;
|
||||
+ return 0;
|
||||
+ case 5:
|
||||
+ *intval = 2500000;
|
||||
+ return 0;
|
||||
+ case 6:
|
||||
+ *intval = 3000000;
|
||||
+ return 0;
|
||||
+ case 7:
|
||||
+ *intval = 3500000;
|
||||
+ return 0;
|
||||
+ default:
|
||||
+ *intval = 4000000;
|
||||
+ return 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static int axp20x_get_current_max(struct axp20x_usb_power *power, int *val)
|
||||
{
|
||||
unsigned int v;
|
||||
@@ -219,6 +265,11 @@ static int axp20x_usb_power_get_property(struct power_supply *psy,
|
||||
case POWER_SUPPLY_PROP_ONLINE:
|
||||
val->intval = !!(input & AXP20X_PWR_STATUS_VBUS_USED);
|
||||
break;
|
||||
+ case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
|
||||
+ if (power->axp20x_id == AXP813_ID)
|
||||
+ return axp813_usb_power_get_input_current_limit(power,
|
||||
+ &val->intval);
|
||||
+ /* fallthrough */
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -252,6 +303,50 @@ static int axp20x_usb_power_set_voltage_min(struct axp20x_usb_power *power,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
+static int
|
||||
+axp813_usb_power_set_input_current_limit(struct axp20x_usb_power *power,
|
||||
+ int intval)
|
||||
+{
|
||||
+ unsigned int reg;
|
||||
+
|
||||
+ switch (intval) {
|
||||
+ case 100000:
|
||||
+ reg = 0;
|
||||
+ break;
|
||||
+ case 500000:
|
||||
+ reg = 1;
|
||||
+ break;
|
||||
+ case 900000:
|
||||
+ reg = 2;
|
||||
+ break;
|
||||
+ case 1500000:
|
||||
+ reg = 3;
|
||||
+ break;
|
||||
+ case 2000000:
|
||||
+ reg = 4;
|
||||
+ break;
|
||||
+ case 2500000:
|
||||
+ reg = 5;
|
||||
+ break;
|
||||
+ case 3000000:
|
||||
+ reg = 6;
|
||||
+ break;
|
||||
+ case 3500000:
|
||||
+ reg = 7;
|
||||
+ break;
|
||||
+ case 4000000:
|
||||
+ reg = 8;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return regmap_update_bits(power->regmap,
|
||||
+ AXP813_CHRG_CTRL3,
|
||||
+ AXP813_CHRG_CTRL3_VBUS_CUR_LIMIT_MASK,
|
||||
+ reg << AXP813_CHRG_CTRL3_VBUS_CUR_LIMIT_OFFSET);
|
||||
+}
|
||||
+
|
||||
static int axp813_usb_power_set_current_max(struct axp20x_usb_power *power,
|
||||
int intval)
|
||||
{
|
||||
@@ -316,6 +411,11 @@ static int axp20x_usb_power_set_property(struct power_supply *psy,
|
||||
val->intval);
|
||||
return axp20x_usb_power_set_current_max(power, val->intval);
|
||||
|
||||
+ case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
|
||||
+ if (power->axp20x_id == AXP813_ID)
|
||||
+ return axp813_usb_power_set_input_current_limit(power,
|
||||
+ val->intval);
|
||||
+ /* fallthrough */
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -327,7 +427,8 @@ static int axp20x_usb_power_prop_writeable(struct power_supply *psy,
|
||||
enum power_supply_property psp)
|
||||
{
|
||||
return psp == POWER_SUPPLY_PROP_VOLTAGE_MIN ||
|
||||
- psp == POWER_SUPPLY_PROP_CURRENT_MAX;
|
||||
+ psp == POWER_SUPPLY_PROP_CURRENT_MAX ||
|
||||
+ psp == POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT;
|
||||
}
|
||||
|
||||
static enum power_supply_property axp20x_usb_power_properties[] = {
|
||||
@@ -346,6 +447,7 @@ static enum power_supply_property axp22x_usb_power_properties[] = {
|
||||
POWER_SUPPLY_PROP_ONLINE,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_MIN,
|
||||
POWER_SUPPLY_PROP_CURRENT_MAX,
|
||||
+ POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
|
||||
};
|
||||
|
||||
static const struct power_supply_desc axp20x_usb_power_desc = {
|
||||
diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h
|
||||
index 517e60eecbcb..1c968a2e31f7 100644
|
||||
--- a/include/linux/mfd/axp20x.h
|
||||
+++ b/include/linux/mfd/axp20x.h
|
||||
@@ -133,6 +133,7 @@ enum axp20x_variants {
|
||||
|
||||
/* Other DCDC regulator control registers are the same as AXP803 */
|
||||
#define AXP813_DCDC7_V_OUT 0x26
|
||||
+#define AXP813_CHRG_CTRL3 0x35
|
||||
|
||||
/* Interrupt */
|
||||
#define AXP152_IRQ1_EN 0x40
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
From 22b15d77f99612906a02c96b9b926233d187605f Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Thu, 16 Nov 2017 00:30:19 +0100
|
||||
Subject: [PATCH 26/82] mfd: axp20x: Make AXP22X_CHRG_CTRL3 because it is
|
||||
updated by charger det.
|
||||
|
||||
Charger detection updates this to reflect allowed current.
|
||||
|
||||
Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
---
|
||||
drivers/mfd/axp20x.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
|
||||
index 95f36a7e3cd4..81bf6ee4d8bb 100644
|
||||
--- a/drivers/mfd/axp20x.c
|
||||
+++ b/drivers/mfd/axp20x.c
|
||||
@@ -131,6 +131,7 @@ static const struct regmap_range axp288_volatile_ranges[] = {
|
||||
regmap_reg_range(AXP288_BC_GLOBAL, AXP288_BC_GLOBAL),
|
||||
regmap_reg_range(AXP288_BC_DET_STAT, AXP288_BC_DET_STAT),
|
||||
regmap_reg_range(AXP20X_CHRG_BAK_CTRL, AXP20X_CHRG_BAK_CTRL),
|
||||
+ regmap_reg_range(AXP22X_CHRG_CTRL3, AXP22X_CHRG_CTRL3),
|
||||
regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IPSOUT_V_HIGH_L),
|
||||
regmap_reg_range(AXP20X_TIMER_CTRL, AXP20X_TIMER_CTRL),
|
||||
regmap_reg_range(AXP22X_GPIO_STATE, AXP22X_GPIO_STATE),
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
From 5e76e10095d6370a3c7235543acda9b4f256d246 Mon Sep 17 00:00:00 2001
|
||||
From: Tomas Novotny <tomas@novotny.cz>
|
||||
Date: Tue, 24 Oct 2017 15:07:42 +0200
|
||||
Subject: [PATCH 27/82] arm: dts: sun8i: a83t: a711: update brightness levels
|
||||
to fit the device
|
||||
|
||||
The function is exponential with base of 1.32 and some offset and
|
||||
tweaks. The lowest values produce no output, so we are starting at 8.
|
||||
The default brigtness is a bit lower than maximum to boot with reduced
|
||||
backlight.
|
||||
|
||||
Signed-off-by: Tomas Novotny <tomas@novotny.cz>
|
||||
---
|
||||
arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 7 +++++--
|
||||
1 file changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
index dc7b94a6c068..bd7e231e3aba 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
@@ -65,8 +65,11 @@
|
||||
pwms = <&pwm 0 50000 PWM_POLARITY_INVERTED>;
|
||||
enable-gpios = <&pio 3 29 GPIO_ACTIVE_HIGH>;
|
||||
|
||||
- brightness-levels = <0 1 2 4 8 16 32 64 128 255>;
|
||||
- default-brightness-level = <9>;
|
||||
+ brightness-levels = <0 8 9 10 11 13 15 17 19 21 23 25 28
|
||||
+ 31 34 37 40 44 48 52 56 61 67 72 78
|
||||
+ 84 91 98 106 115 124 133 143 154
|
||||
+ 166 179 192 207 223 239 255>;
|
||||
+ default-brightness-level = <39>;
|
||||
};
|
||||
|
||||
panel {
|
||||
--
|
||||
2.20.1
|
||||
|
File diff suppressed because it is too large
Load diff
|
@ -1,30 +0,0 @@
|
|||
From 143f5c46be05234ca2618eb4515b9b1d2f329770 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Sat, 30 Sep 2017 21:31:35 +0200
|
||||
Subject: [PATCH 29/82] MAINTAINERS: Add entry for Himax HM5065
|
||||
|
||||
Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
---
|
||||
MAINTAINERS | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/MAINTAINERS b/MAINTAINERS
|
||||
index 11a59e82d92e..93f4ff7d6eba 100644
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -6611,6 +6611,12 @@ S: Supported
|
||||
F: Documentation/scsi/hptiop.txt
|
||||
F: drivers/scsi/hptiop.c
|
||||
|
||||
+HIMAX HM5065 SENSOR DRIVER
|
||||
+M: Ondrej Jirman <kernel@xff.cz>
|
||||
+L: linux-media@vger.kernel.org
|
||||
+S: Supported
|
||||
+F: drivers/media/i2c/hm5065.c
|
||||
+
|
||||
HIPPI
|
||||
M: Jes Sorensen <jes@trained-monkey.org>
|
||||
L: linux-hippi@sunsite.dk
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
From 086f56910cfcc26939c56dfd143c7ee3dc24cff1 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Sat, 30 Sep 2017 02:30:39 +0200
|
||||
Subject: [PATCH 30/82] media: dt-bindings: Add bindings for Himax HM5065
|
||||
camera sensor
|
||||
|
||||
HM5065 is 5MP CMOS sensor...
|
||||
|
||||
Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
---
|
||||
.../devicetree/bindings/media/i2c/hm5065.txt | 48 +++++++++++++++++++
|
||||
1 file changed, 48 insertions(+)
|
||||
create mode 100644 Documentation/devicetree/bindings/media/i2c/hm5065.txt
|
||||
|
||||
diff --git a/Documentation/devicetree/bindings/media/i2c/hm5065.txt b/Documentation/devicetree/bindings/media/i2c/hm5065.txt
|
||||
new file mode 100644
|
||||
index 000000000000..68ad7f529e18
|
||||
--- /dev/null
|
||||
+++ b/Documentation/devicetree/bindings/media/i2c/hm5065.txt
|
||||
@@ -0,0 +1,48 @@
|
||||
+* Himax HM5065 CSI camera sensor
|
||||
+
|
||||
+Required Properties:
|
||||
+- compatible: should be "himax,hm5065"
|
||||
+- clocks: reference to the external input clock for the sensor.
|
||||
+- clock-names: should be "xclk".
|
||||
+- IOVDD-supply: Digital I/O voltage supply, 2.8 volts
|
||||
+- AVDD-supply: Analog voltage supply, 2.8 volts
|
||||
+- DVDD-supply: Digital core voltage supply, 1.8 volts
|
||||
+- AFVDD-supply: Auto focus voltage supply, 2.8 volts
|
||||
+
|
||||
+Optional Properties (one or both must be configured):
|
||||
+- reset-gpios: reference to the GPIO connected to the reset pin, if any.
|
||||
+ This is an active low signal to the HM5065.
|
||||
+- chipenable-gpios: reference to the GPIO connected to the CE pin,
|
||||
+ if any. This is an active high signal to the HM5065.
|
||||
+
|
||||
+The device node must contain one 'port' child node for its digital output
|
||||
+video port, in accordance with the video interface bindings defined in
|
||||
+Documentation/devicetree/bindings/media/video-interfaces.txt.
|
||||
+
|
||||
+Example:
|
||||
+
|
||||
+&i2c1 {
|
||||
+ hm5065: camera@1f {
|
||||
+ compatible = "himax,hm5065";
|
||||
+ reg = <0x1f>;
|
||||
+ clocks = <&ccu CLK_CSI_MCLK>;
|
||||
+ clock-names = "xclk";
|
||||
+ IOVDD-supply = <®_dldo3>;
|
||||
+ AVDD-supply = <®_dldo4>;
|
||||
+ DVDD-supply = <®_eldo3>;
|
||||
+ AFVDD-supply = <®_dldo3>;
|
||||
+ reset-gpios = <&pio 4 18 GPIO_ACTIVE_LOW>; /* PE18 */
|
||||
+ chipenable-gpios = <&pio 4 19 GPIO_ACTIVE_HIGH>; /* PE19 */
|
||||
+
|
||||
+ port {
|
||||
+ hm5065_ep: endpoint {
|
||||
+ remote-endpoint = <&csi0_hm5065_ep>;
|
||||
+ bus-width = <8>;
|
||||
+ hsync-active = <1>;
|
||||
+ vsync-active = <1>;
|
||||
+ data-active = <1>;
|
||||
+ pclk-sample = <1>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
From 7fe79d7ef105939f10903d87c44b8ea4da3bc4ae Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Sat, 30 Sep 2017 02:46:55 +0200
|
||||
Subject: [PATCH 31/82] ARM: dts: sun8i-a83t: Add CSI0 node for cmos sensor
|
||||
interface driver
|
||||
|
||||
Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
---
|
||||
arch/arm/boot/dts/sun8i-a83t.dtsi | 21 +++++++++++++++++++++
|
||||
1 file changed, 21 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi
|
||||
index 00a02b037320..66f035ead79a 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-a83t.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
|
||||
@@ -636,6 +636,20 @@
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
|
||||
+ csi0: csi@01cb0000 {
|
||||
+ compatible = "allwinner,sun8i-a83t-csi";
|
||||
+ reg = <0x01cb0000 0x1000>; /* manual says 0x40000 size */
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ clocks = <&ccu CLK_BUS_CSI>,
|
||||
+ <&ccu CLK_CSI_SCLK>,
|
||||
+ <&ccu CLK_DRAM_CSI>;
|
||||
+ clock-names = "ahb", "mod", "ram";
|
||||
+ resets = <&ccu RST_BUS_CSI>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
pio: pinctrl@1c20800 {
|
||||
compatible = "allwinner,sun8i-a83t-pinctrl";
|
||||
interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
|
||||
@@ -649,6 +663,13 @@
|
||||
#interrupt-cells = <3>;
|
||||
#gpio-cells = <3>;
|
||||
|
||||
+ csi0_pins: csi0-pins {
|
||||
+ pins = "PE0", "PE1", "PE2", "PE3", "PE4",
|
||||
+ "PE5", "PE6", "PE7", "PE8", "PE9",
|
||||
+ "PE10", "PE11", "PE12", "PE13";
|
||||
+ function = "csi";
|
||||
+ };
|
||||
+
|
||||
emac_rgmii_pins: emac-rgmii-pins {
|
||||
pins = "PD2", "PD3", "PD4", "PD5", "PD6", "PD7",
|
||||
"PD11", "PD12", "PD13", "PD14", "PD18",
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
From ac8826aeb1f157a76b1f1d31b13eb557d3f96108 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Sat, 30 Sep 2017 02:53:26 +0200
|
||||
Subject: [PATCH 32/82] ARM: dts: sun8i-a83t-tbs-a711: Force dvdd-csi-r/f
|
||||
regulators to 1.8V
|
||||
|
||||
This is required by camera sensors that are connected to them.
|
||||
|
||||
Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
---
|
||||
arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
index bd7e231e3aba..7936405862c1 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
@@ -353,7 +353,7 @@
|
||||
};
|
||||
|
||||
®_eldo1 {
|
||||
- regulator-min-microvolt = <1200000>;
|
||||
+ regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
regulator-name = "dvdd-csi-r";
|
||||
};
|
||||
@@ -365,7 +365,7 @@
|
||||
};
|
||||
|
||||
®_eldo3 {
|
||||
- regulator-min-microvolt = <1200000>;
|
||||
+ regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
regulator-name = "dvdd-csi-f";
|
||||
};
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
From 0ba507d286fc521e71ba048d81c7d1d751012bb8 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Sat, 30 Sep 2017 02:51:09 +0200
|
||||
Subject: [PATCH 33/82] ARM: dts: sun8i-a83t-tbs-a711: Use i2c-gpio to
|
||||
communicate with cameras
|
||||
|
||||
Camera sensors are connected via I2C to PE14/PE15 pins on A83T.
|
||||
Unfortunately while the A83T datasheet suggests TWI2 I2C controller
|
||||
can be configured to have SDA/SCL on these pins, this configuration
|
||||
doesn't work in reality. We need to either use CCI I2C controller
|
||||
that is part of the CSI module, or as is done in this patch, use GPIO
|
||||
based bitbanging I2C driver.
|
||||
|
||||
Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
---
|
||||
arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
index 7936405862c1..8a0a8d39eb21 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
@@ -72,6 +72,16 @@
|
||||
default-brightness-level = <39>;
|
||||
};
|
||||
|
||||
+ i2c_gpio: i2c-gpio {
|
||||
+ compatible = "i2c-gpio";
|
||||
+ /* PE15 = sda, PE14 = scl */
|
||||
+ sda-gpios = <&pio 4 15 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
|
||||
+ scl-gpios = <&pio 4 14 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
|
||||
+ i2c-gpio,delay-us = <1>; /* ~100 kHz */
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <0>;
|
||||
+ };
|
||||
+
|
||||
panel {
|
||||
compatible = "tbs,a711-panel", "panel-lvds";
|
||||
backlight = <&backlight>;
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
From 5436d28adbf6268496e20b4c43c43a59f597c340 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Tue, 10 Oct 2017 05:26:49 +0200
|
||||
Subject: [PATCH 34/82] ARM: dts: sun8i-a83t-tbs-a711: Add rear camera sensor
|
||||
(HM5065)
|
||||
|
||||
Sensor is connected via parallel bus to CSI0 and via I2C bus to
|
||||
PE14/PE15 pins. Enable CSI0 module and add the node for HM5065
|
||||
camera sensor.
|
||||
|
||||
Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
---
|
||||
arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 43 +++++++++++++++++++++++
|
||||
1 file changed, 43 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
index 8a0a8d39eb21..9a87ce651224 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
@@ -149,6 +149,23 @@
|
||||
cpu-supply = <®_dcdc3>;
|
||||
};
|
||||
|
||||
+&csi0 {
|
||||
+ status = "okay";
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&csi0_pins>;
|
||||
+
|
||||
+ port {
|
||||
+ csi0_hm5065_ep: endpoint {
|
||||
+ remote-endpoint = <&hm5065_ep>;
|
||||
+ bus-width = <8>;
|
||||
+ data-active = <1>;
|
||||
+ pclk-sample = <1>;
|
||||
+ hsync-active = <1>;
|
||||
+ vsync-active = <0>;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
&de {
|
||||
status = "okay";
|
||||
};
|
||||
@@ -185,6 +202,32 @@
|
||||
};
|
||||
};
|
||||
|
||||
+&i2c_gpio {
|
||||
+ hm5065: camera@1f {
|
||||
+ compatible = "himax,hm5065";
|
||||
+ reg = <0x1f>;
|
||||
+ clocks = <&ccu CLK_CSI_MCLK>;
|
||||
+ clock-names = "xclk";
|
||||
+ IOVDD-supply = <®_dldo3>;
|
||||
+ AVDD-supply = <®_dldo4>;
|
||||
+ DVDD-supply = <®_eldo3>;
|
||||
+ AFVDD-supply = <®_dldo3>;
|
||||
+ reset-gpios = <&pio 4 18 GPIO_ACTIVE_LOW>; /* PE18 */
|
||||
+ chipenable-gpios = <&pio 4 19 GPIO_ACTIVE_HIGH>; /* PE19 */
|
||||
+
|
||||
+ port {
|
||||
+ hm5065_ep: endpoint {
|
||||
+ remote-endpoint = <&csi0_hm5065_ep>;
|
||||
+ bus-width = <8>;
|
||||
+ data-active = <1>;
|
||||
+ pclk-sample = <1>;
|
||||
+ hsync-active = <1>;
|
||||
+ vsync-active = <0>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
&mmc0 {
|
||||
vmmc-supply = <®_dcdc1>;
|
||||
pinctrl-names = "default";
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
From 0f0c62c90fc072355b2118d118715492710b8735 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Wed, 8 Nov 2017 04:55:15 +0100
|
||||
Subject: [PATCH 35/82] ARM: dts: sun8i-a83t-tbs-a711: Reduce camera IOVDD
|
||||
voltage
|
||||
|
||||
---
|
||||
arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
index 9a87ce651224..1a711a28f682 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
@@ -389,8 +389,8 @@
|
||||
};
|
||||
|
||||
®_dldo3 {
|
||||
- regulator-min-microvolt = <2800000>;
|
||||
- regulator-max-microvolt = <2800000>;
|
||||
+ regulator-min-microvolt = <2600000>;
|
||||
+ regulator-max-microvolt = <2600000>;
|
||||
regulator-name = "vdd-csi";
|
||||
};
|
||||
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
From acfec807289ebf7c2af8aaf75aaa67159d549734 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Wed, 8 Nov 2017 21:57:45 +0100
|
||||
Subject: [PATCH 36/82] ARM: dts: sun8i-a83t-tbs-a711: Add flash led support
|
||||
|
||||
---
|
||||
arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
index 1a711a28f682..c8278e173f50 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
@@ -60,6 +60,15 @@
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
|
||||
+ leds {
|
||||
+ compatible = "gpio-leds";
|
||||
+
|
||||
+ flash_led {
|
||||
+ label = "flash";
|
||||
+ gpios = <&pio 1 3 GPIO_ACTIVE_HIGH>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
backlight: backlight {
|
||||
compatible = "pwm-backlight";
|
||||
pwms = <&pwm 0 50000 PWM_POLARITY_INVERTED>;
|
||||
--
|
||||
2.20.1
|
||||
|
File diff suppressed because it is too large
Load diff
|
@ -1,34 +0,0 @@
|
|||
From dd149592ded2be2ebbe64ee83bcb34054470cf07 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Thu, 9 Nov 2017 23:05:13 +0100
|
||||
Subject: [PATCH 38/82] arm: dts: sun8i: a83t: a711: Enable I2C1
|
||||
|
||||
The A711 has some sensors connected to I2C1. Enable only the bus for the
|
||||
moment.
|
||||
|
||||
Signed-off-by: Tomas Novotny <tomas@novotny.cz>
|
||||
---
|
||||
arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
index c8278e173f50..8e9f0de3d0c0 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
@@ -237,6 +237,13 @@
|
||||
};
|
||||
};
|
||||
|
||||
+&i2c1 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&i2c1_pins>;
|
||||
+ clock-frequency = <400000>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&mmc0 {
|
||||
vmmc-supply = <®_dcdc1>;
|
||||
pinctrl-names = "default";
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
From 69c8e0651bb68ab80b0fc4033b8ca5e87b8bb164 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Fri, 10 Nov 2017 13:20:43 +0100
|
||||
Subject: [PATCH 39/82] ARM: dts: sun8i-a83t-tbs-a711: Enable BMA250
|
||||
accelerometer IIO
|
||||
|
||||
It's already supported in mainline kernel.
|
||||
|
||||
Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
---
|
||||
arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
index 8e9f0de3d0c0..2427bf3461d7 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
@@ -242,6 +242,14 @@
|
||||
pinctrl-0 = <&i2c1_pins>;
|
||||
clock-frequency = <400000>;
|
||||
status = "okay";
|
||||
+
|
||||
+ /* Accelerometer */
|
||||
+ bma250@18 {
|
||||
+ compatible = "bosch,bma250";
|
||||
+ reg = <0x18>;
|
||||
+ interrupt-parent = <&pio>;
|
||||
+ interrupts = <7 10 IRQ_TYPE_EDGE_RISING>; /* PH10 / EINT10 */
|
||||
+ };
|
||||
};
|
||||
|
||||
&mmc0 {
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
From 113d3049c946e68e32fdec6f64672fe4cd181cc8 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Fri, 10 Nov 2017 13:21:55 +0100
|
||||
Subject: [PATCH 40/82] ARM: dts: sun8i-a83t-tbs-a711: Enable LTR-501-ALS IIO
|
||||
|
||||
It's already supported in mainline kernel. Though, the driver didn't
|
||||
have OF compativles table.
|
||||
|
||||
Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
---
|
||||
arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
index 2427bf3461d7..6acc678d1b5b 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
@@ -250,6 +250,15 @@
|
||||
interrupt-parent = <&pio>;
|
||||
interrupts = <7 10 IRQ_TYPE_EDGE_RISING>; /* PH10 / EINT10 */
|
||||
};
|
||||
+
|
||||
+ /* Light Sensor */
|
||||
+ ltr501: ltr501@23 {
|
||||
+ status = "disabled"; /* no output */
|
||||
+ compatible = "ltr,ltr501";
|
||||
+ reg = <0x23>;
|
||||
+ interrupt-parent = <&pio>;
|
||||
+ interrupts = <6 12 IRQ_TYPE_EDGE_FALLING>; /* PG12 */
|
||||
+ };
|
||||
};
|
||||
|
||||
&mmc0 {
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
From e4548a8a5ad34919a94b282369212b661e1d4382 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Fri, 10 Nov 2017 13:23:01 +0100
|
||||
Subject: [PATCH 41/82] iio: ltr501: Add OF compatibles
|
||||
|
||||
So that driver can be configured from DTS.
|
||||
|
||||
Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
---
|
||||
drivers/iio/light/ltr501.c | 18 ++++++++++++++++--
|
||||
1 file changed, 16 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/iio/light/ltr501.c b/drivers/iio/light/ltr501.c
|
||||
index 830a2d45aa4d..bdb296dcb7c0 100644
|
||||
--- a/drivers/iio/light/ltr501.c
|
||||
+++ b/drivers/iio/light/ltr501.c
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/acpi.h>
|
||||
+#include <linux/of.h>
|
||||
|
||||
#include <linux/iio/iio.h>
|
||||
#include <linux/iio/events.h>
|
||||
@@ -1558,6 +1559,7 @@ static int ltr501_resume(struct device *dev)
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(ltr501_pm_ops, ltr501_suspend, ltr501_resume);
|
||||
|
||||
+#ifdef CONFIG_ACPI
|
||||
static const struct acpi_device_id ltr_acpi_match[] = {
|
||||
{"LTER0501", ltr501},
|
||||
{"LTER0559", ltr559},
|
||||
@@ -1565,6 +1567,7 @@ static const struct acpi_device_id ltr_acpi_match[] = {
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, ltr_acpi_match);
|
||||
+#endif
|
||||
|
||||
static const struct i2c_device_id ltr501_id[] = {
|
||||
{ "ltr501", ltr501},
|
||||
@@ -1574,11 +1577,22 @@ static const struct i2c_device_id ltr501_id[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, ltr501_id);
|
||||
|
||||
+#ifdef CONFIG_OF
|
||||
+static const struct of_device_id ltr501_of_match[] = {
|
||||
+ { .compatible = "ltr,ltr501", .data = (void*)ltr501 },
|
||||
+ { .compatible = "ltr,ltr559", .data = (void*)ltr559 },
|
||||
+ { .compatible = "ltr,ltr301", .data = (void*)ltr301 },
|
||||
+ { }
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, ltr501_of_match);
|
||||
+#endif
|
||||
+
|
||||
static struct i2c_driver ltr501_driver = {
|
||||
.driver = {
|
||||
- .name = LTR501_DRV_NAME,
|
||||
- .pm = <r501_pm_ops,
|
||||
+ .name = LTR501_DRV_NAME,
|
||||
+ .pm = <r501_pm_ops,
|
||||
.acpi_match_table = ACPI_PTR(ltr_acpi_match),
|
||||
+ .of_match_table = of_match_ptr(ltr501_of_match)
|
||||
},
|
||||
.probe = ltr501_probe,
|
||||
.remove = ltr501_remove,
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
From 2a3460a07d4ef36bd754c83dce9b6b7ea9844aa3 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Fri, 10 Nov 2017 13:24:58 +0100
|
||||
Subject: [PATCH 42/82] ARM: dts: sun8i-a83t-tbs-a711: Enable AK8963
|
||||
magnetometer
|
||||
|
||||
Though the chip is probably broken on my tablet. It doesn't respond
|
||||
on I2C 0x0d address.
|
||||
|
||||
Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
---
|
||||
arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 18 ++++++++++++++++++
|
||||
1 file changed, 18 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
index 6acc678d1b5b..ec986498114e 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
@@ -251,6 +251,24 @@
|
||||
interrupts = <7 10 IRQ_TYPE_EDGE_RISING>; /* PH10 / EINT10 */
|
||||
};
|
||||
|
||||
+ /* Magnetic Sensor */
|
||||
+ ak8963: ak8963@0d {
|
||||
+ status = "disabled"; /* broken */
|
||||
+ compatible = "asahi-kasei,ak8963";
|
||||
+ reg = <0x0d>;
|
||||
+ interrupt-parent = <&pio>;
|
||||
+ interrupts = <1 2 IRQ_TYPE_EDGE_RISING>; /* PB2 */
|
||||
+ mount-matrix = /* x0 */ "-0.984807753012208",
|
||||
+ /* y0 */ "0",
|
||||
+ /* z0 */ "-0.173648177666930",
|
||||
+ /* x1 */ "0",
|
||||
+ /* y1 */ "-1",
|
||||
+ /* z1 */ "0",
|
||||
+ /* x2 */ "-0.173648177666930",
|
||||
+ /* y2 */ "0",
|
||||
+ /* z2 */ "0.984807753012208";
|
||||
+ };
|
||||
+
|
||||
/* Light Sensor */
|
||||
ltr501: ltr501@23 {
|
||||
status = "disabled"; /* no output */
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
From 8df4a460c0459b0ba6a20634adc4ecb60b8e89d5 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Fri, 10 Nov 2017 14:29:26 +0100
|
||||
Subject: [PATCH 43/82] nfc: pn544: Add support for VBAT/PVDD regulators
|
||||
|
||||
Regulators are required, so this can't go into mainline as is.
|
||||
|
||||
Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
---
|
||||
drivers/nfc/pn544/i2c.c | 29 +++++++++++++++++++++++++++--
|
||||
1 file changed, 27 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/nfc/pn544/i2c.c b/drivers/nfc/pn544/i2c.c
|
||||
index d0207f8e68b7..5d0a20d3f9c8 100644
|
||||
--- a/drivers/nfc/pn544/i2c.c
|
||||
+++ b/drivers/nfc/pn544/i2c.c
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <linux/nfc.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
+#include <linux/regulator/consumer.h>
|
||||
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
@@ -70,6 +71,14 @@ MODULE_DEVICE_TABLE(acpi, pn544_hci_i2c_acpi_match);
|
||||
|
||||
#define PN544_HCI_I2C_DRIVER_NAME "pn544_hci_i2c"
|
||||
|
||||
+/* regulator supplies */
|
||||
+static const char * const pn544_supply_names[] = {
|
||||
+ "PVDD", /* Digital Core (1.8V) supply */
|
||||
+ "VBAT", /* Analog (2.9V-5.5V) supply */
|
||||
+};
|
||||
+
|
||||
+#define PN544_NUM_SUPPLIES ARRAY_SIZE(pn544_supply_names)
|
||||
+
|
||||
/*
|
||||
* Exposed through the 4 most significant bytes
|
||||
* from the HCI SW_VERSION first byte, a.k.a.
|
||||
@@ -161,6 +170,7 @@ struct pn544_i2c_phy {
|
||||
struct i2c_client *i2c_dev;
|
||||
struct nfc_hci_dev *hdev;
|
||||
|
||||
+ struct regulator_bulk_data supplies[PN544_NUM_SUPPLIES];
|
||||
struct gpio_desc *gpiod_en;
|
||||
struct gpio_desc *gpiod_fw;
|
||||
|
||||
@@ -250,9 +260,14 @@ static void pn544_hci_i2c_enable_mode(struct pn544_i2c_phy *phy, int run_mode)
|
||||
static int pn544_hci_i2c_enable(void *phy_id)
|
||||
{
|
||||
struct pn544_i2c_phy *phy = phy_id;
|
||||
+ int ret;
|
||||
|
||||
pr_info("%s\n", __func__);
|
||||
|
||||
+ ret = regulator_bulk_enable(PN544_NUM_SUPPLIES, phy->supplies);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
pn544_hci_i2c_enable_mode(phy, PN544_HCI_MODE);
|
||||
|
||||
phy->powered = 1;
|
||||
@@ -274,6 +289,8 @@ static void pn544_hci_i2c_disable(void *phy_id)
|
||||
gpiod_set_value_cansleep(phy->gpiod_en, !phy->en_polarity);
|
||||
usleep_range(10000, 15000);
|
||||
|
||||
+ regulator_bulk_disable(PN544_NUM_SUPPLIES, phy->supplies);
|
||||
+
|
||||
phy->powered = 0;
|
||||
}
|
||||
|
||||
@@ -380,7 +397,7 @@ static int pn544_hci_i2c_read(struct pn544_i2c_phy *phy, struct sk_buff **skb)
|
||||
|
||||
if ((len < (PN544_HCI_I2C_LLC_MIN_SIZE - 1)) ||
|
||||
(len > (PN544_HCI_I2C_LLC_MAX_SIZE - 1))) {
|
||||
- nfc_err(&client->dev, "invalid len byte\n");
|
||||
+ nfc_err(&client->dev, "invalid len byte %hhx\n", len);
|
||||
r = -EBADMSG;
|
||||
goto flush;
|
||||
}
|
||||
@@ -883,7 +900,7 @@ static int pn544_hci_i2c_probe(struct i2c_client *client,
|
||||
{
|
||||
struct device *dev = &client->dev;
|
||||
struct pn544_i2c_phy *phy;
|
||||
- int r = 0;
|
||||
+ int r = 0, i;
|
||||
|
||||
dev_dbg(&client->dev, "%s\n", __func__);
|
||||
dev_dbg(&client->dev, "IRQ: %d\n", client->irq);
|
||||
@@ -908,6 +925,14 @@ static int pn544_hci_i2c_probe(struct i2c_client *client,
|
||||
if (r)
|
||||
dev_dbg(dev, "Unable to add GPIO mapping table\n");
|
||||
|
||||
+ for (i = 0; i < PN544_NUM_SUPPLIES; i++)
|
||||
+ phy->supplies[i].supply = pn544_supply_names[i];
|
||||
+
|
||||
+ r = devm_regulator_bulk_get(&client->dev, PN544_NUM_SUPPLIES,
|
||||
+ phy->supplies);
|
||||
+ if (r)
|
||||
+ return r;
|
||||
+
|
||||
/* Get EN GPIO */
|
||||
phy->gpiod_en = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(phy->gpiod_en)) {
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
From 69eafa62d60b993ba9500f56af568357b16b1504 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Fri, 10 Nov 2017 14:33:28 +0100
|
||||
Subject: [PATCH 44/82] ARM: dts: sun8i-a83t-tbs-a711: Add PN544 NFC support
|
||||
|
||||
Regulators on the schematic are named incorrectly. Both cameras are
|
||||
is in fact connected to the dvdd-csi-f regulator and dvdd-csi-r is
|
||||
in reality used for digital pad supply for NFC chip.
|
||||
|
||||
At the same time vcc-mipi regulator is not used for MIPI, but for NFC
|
||||
VBAT power.
|
||||
|
||||
Interpreting schematics is an art form! :D
|
||||
|
||||
Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
---
|
||||
arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 18 +++++++++++++++---
|
||||
1 file changed, 15 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
index ec986498114e..787277f4d455 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
@@ -277,6 +277,16 @@
|
||||
interrupt-parent = <&pio>;
|
||||
interrupts = <6 12 IRQ_TYPE_EDGE_FALLING>; /* PG12 */
|
||||
};
|
||||
+
|
||||
+ /* NFC (NPC 100) */
|
||||
+ npc100: nfc@28 {
|
||||
+ compatible = "nxp,nxp-nci-i2c";
|
||||
+ reg = <0x28>;
|
||||
+ interrupt-parent = <&r_pio>;
|
||||
+ interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>; /* PL6 */
|
||||
+ enable-gpios = <&pio 3 2 GPIO_ACTIVE_HIGH>; /* PD2 */
|
||||
+ firmware-gpios = <&pio 3 3 GPIO_ACTIVE_HIGH>; /* PD3 */
|
||||
+ };
|
||||
};
|
||||
|
||||
&mmc0 {
|
||||
@@ -434,9 +444,10 @@
|
||||
};
|
||||
|
||||
®_dldo2 {
|
||||
- regulator-min-microvolt = <2800000>;
|
||||
+ regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <4200000>;
|
||||
- regulator-name = "vcc-mipi";
|
||||
+ regulator-name = "vbat-nfc";
|
||||
+ regulator-always-on;
|
||||
};
|
||||
|
||||
®_dldo3 {
|
||||
@@ -459,7 +470,8 @@
|
||||
®_eldo1 {
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
- regulator-name = "dvdd-csi-r";
|
||||
+ regulator-name = "pvdd-nfc";
|
||||
+ regulator-always-on;
|
||||
};
|
||||
|
||||
®_eldo2 {
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,104 +0,0 @@
|
|||
From df802a8e12f7600dea15f67314bb1bfd7a981949 Mon Sep 17 00:00:00 2001
|
||||
From: Ziping Chen <techping.chan@gmail.com>
|
||||
Date: Mon, 13 Nov 2017 16:49:37 +0100
|
||||
Subject: [PATCH 45/82] input: sun4i-a10-lradc-keys: Add support for A83T
|
||||
|
||||
Allwinner A83T SoC has a low res adc like the one
|
||||
in Allwinner A10 SoC, however, the A10 SoC's vref
|
||||
of lradc internally is divided by 2/3 and the A83T
|
||||
SoC's vref of lradc internally is divided by 3/4,
|
||||
thus add a hardware variant for it to be compatible
|
||||
with various devices.
|
||||
|
||||
Signed-off-by: Ziping Chen <techping.chan@gmail.com>
|
||||
---
|
||||
drivers/input/keyboard/sun4i-lradc-keys.c | 38 ++++++++++++++++++++---
|
||||
1 file changed, 34 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/input/keyboard/sun4i-lradc-keys.c b/drivers/input/keyboard/sun4i-lradc-keys.c
|
||||
index a37c172452e6..bfd2038a9047 100644
|
||||
--- a/drivers/input/keyboard/sun4i-lradc-keys.c
|
||||
+++ b/drivers/input/keyboard/sun4i-lradc-keys.c
|
||||
@@ -46,6 +46,7 @@
|
||||
#define CONTINUE_TIME_SEL(x) ((x) << 16) /* 4 bits */
|
||||
#define KEY_MODE_SEL(x) ((x) << 12) /* 2 bits */
|
||||
#define LEVELA_B_CNT(x) ((x) << 8) /* 4 bits */
|
||||
+#define HOLD_KEY_EN(x) ((x) << 7)
|
||||
#define HOLD_EN(x) ((x) << 6)
|
||||
#define LEVELB_VOL(x) ((x) << 4) /* 2 bits */
|
||||
#define SAMPLE_RATE(x) ((x) << 2) /* 2 bits */
|
||||
@@ -63,6 +64,25 @@
|
||||
#define CHAN0_KEYDOWN_IRQ BIT(1)
|
||||
#define CHAN0_DATA_IRQ BIT(0)
|
||||
|
||||
+/* struct lradc_variant - Describe sun4i-a10-lradc-keys hardware variant
|
||||
+ * @divisor_numerator: The numerator of lradc Vref internally divisor
|
||||
+ * @divisor_denominator: The denominator of lradc Vref internally divisor
|
||||
+ */
|
||||
+struct lradc_variant {
|
||||
+ u8 divisor_numerator;
|
||||
+ u8 divisor_denominator;
|
||||
+};
|
||||
+
|
||||
+static const struct lradc_variant lradc_variant_a10 = {
|
||||
+ .divisor_numerator = 2,
|
||||
+ .divisor_denominator = 3
|
||||
+};
|
||||
+
|
||||
+static const struct lradc_variant r_lradc_variant_a83t = {
|
||||
+ .divisor_numerator = 3,
|
||||
+ .divisor_denominator = 4
|
||||
+};
|
||||
+
|
||||
struct sun4i_lradc_keymap {
|
||||
u32 voltage;
|
||||
u32 keycode;
|
||||
@@ -74,6 +94,7 @@ struct sun4i_lradc_data {
|
||||
void __iomem *base;
|
||||
struct regulator *vref_supply;
|
||||
struct sun4i_lradc_keymap *chan0_map;
|
||||
+ const struct lradc_variant *variant;
|
||||
u32 chan0_map_count;
|
||||
u32 chan0_keycode;
|
||||
u32 vref;
|
||||
@@ -128,9 +149,9 @@ static int sun4i_lradc_open(struct input_dev *dev)
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
- /* lradc Vref internally is divided by 2/3 */
|
||||
- lradc->vref = regulator_get_voltage(lradc->vref_supply) * 2 / 3;
|
||||
-
|
||||
+ lradc->vref = regulator_get_voltage(lradc->vref_supply) *
|
||||
+ lradc->variant->divisor_numerator /
|
||||
+ lradc->variant->divisor_denominator;
|
||||
/*
|
||||
* Set sample time to 4 ms / 250 Hz. Wait 2 * 4 ms for key to
|
||||
* stabilize on press, wait (1 + 1) * 4 ms for key release
|
||||
@@ -222,6 +243,12 @@ static int sun4i_lradc_probe(struct platform_device *pdev)
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
+ lradc->variant = of_device_get_match_data(&pdev->dev);
|
||||
+ if (!lradc->variant) {
|
||||
+ dev_err(&pdev->dev, "Missing sun4i-a10-lradc-keys variant\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
lradc->vref_supply = devm_regulator_get(dev, "vref");
|
||||
if (IS_ERR(lradc->vref_supply))
|
||||
return PTR_ERR(lradc->vref_supply);
|
||||
@@ -265,7 +292,10 @@ static int sun4i_lradc_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
static const struct of_device_id sun4i_lradc_of_match[] = {
|
||||
- { .compatible = "allwinner,sun4i-a10-lradc-keys", },
|
||||
+ { .compatible = "allwinner,sun4i-a10-lradc-keys",
|
||||
+ .data = &lradc_variant_a10 },
|
||||
+ { .compatible = "allwinner,sun8i-a83t-r-lradc-keys",
|
||||
+ .data = &r_lradc_variant_a83t },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sun4i_lradc_of_match);
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
From b804df86f96f4bdc74abab55404a0bdcc7526f8b Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Sun, 12 Nov 2017 06:25:17 +0100
|
||||
Subject: [PATCH 46/82] ARM: dts: sun8i-a83t: Add lradc
|
||||
|
||||
Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
---
|
||||
arch/arm/boot/dts/sun8i-a83t.dtsi | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi
|
||||
index 66f035ead79a..d9074f050a9c 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-a83t.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
|
||||
@@ -627,6 +627,13 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
+ lradc: lradc@1f03c00 {
|
||||
+ compatible = "allwinner,sun4i-a10-lradc-keys";
|
||||
+ reg = <0x01f03c00 0x100>;
|
||||
+ interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
ccu: clock@1c20000 {
|
||||
compatible = "allwinner,sun8i-a83t-ccu";
|
||||
reg = <0x01c20000 0x400>;
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
From 8c120e82a6cd86742dbdfd5c0a17d88737a74394 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Sun, 12 Nov 2017 06:25:59 +0100
|
||||
Subject: [PATCH 47/82] ARM: dts: sun8i-a83t-tbs-a711: Add support for volume
|
||||
keys input
|
||||
|
||||
Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
---
|
||||
arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 20 ++++++++++++++++++++
|
||||
1 file changed, 20 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
index 787277f4d455..ab4dce4b1e67 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
@@ -46,6 +46,7 @@
|
||||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/pwm/pwm.h>
|
||||
+#include <dt-bindings/input/input.h>
|
||||
|
||||
/ {
|
||||
model = "TBS A711 Tablet";
|
||||
@@ -289,6 +290,25 @@
|
||||
};
|
||||
};
|
||||
|
||||
+&lradc {
|
||||
+ vref-supply = <®_aldo2>;
|
||||
+ status = "okay";
|
||||
+
|
||||
+ button@200 {
|
||||
+ label = "Volume Up";
|
||||
+ linux,code = <KEY_VOLUMEUP>;
|
||||
+ channel = <0>;
|
||||
+ voltage = <210000>;
|
||||
+ };
|
||||
+
|
||||
+ button@400 {
|
||||
+ label = "Volume Down";
|
||||
+ linux,code = <KEY_VOLUMEDOWN>;
|
||||
+ channel = <0>;
|
||||
+ voltage = <410000>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
&mmc0 {
|
||||
vmmc-supply = <®_dcdc1>;
|
||||
pinctrl-names = "default";
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,544 +0,0 @@
|
|||
From 050ae3acc34834c56ee0a95ed2e96143e4f885b5 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Sun, 12 Nov 2017 02:10:15 +0100
|
||||
Subject: [PATCH 48/82] misc: tbs-a711: Power manager and wakeup monitoring
|
||||
driver
|
||||
|
||||
This driver allows for powering/resetting devices that are otherwise
|
||||
handled by other subsytems (USB). It also has mechanismsm for polling
|
||||
from userspace on device->SoC wakeup events via GPIO.
|
||||
|
||||
Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
---
|
||||
drivers/misc/Makefile | 1 +
|
||||
drivers/misc/tbs-a711.c | 509 ++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 510 insertions(+)
|
||||
create mode 100644 drivers/misc/tbs-a711.c
|
||||
|
||||
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
|
||||
index af22bbc3d00c..4b09a5b406e0 100644
|
||||
--- a/drivers/misc/Makefile
|
||||
+++ b/drivers/misc/Makefile
|
||||
@@ -58,3 +58,4 @@ obj-$(CONFIG_ASPEED_LPC_SNOOP) += aspeed-lpc-snoop.o
|
||||
obj-$(CONFIG_PCI_ENDPOINT_TEST) += pci_endpoint_test.o
|
||||
obj-$(CONFIG_OCXL) += ocxl/
|
||||
obj-$(CONFIG_MISC_RTSX) += cardreader/
|
||||
+obj-y += tbs-a711.o
|
||||
diff --git a/drivers/misc/tbs-a711.c b/drivers/misc/tbs-a711.c
|
||||
new file mode 100644
|
||||
index 000000000000..05fe2ed76429
|
||||
--- /dev/null
|
||||
+++ b/drivers/misc/tbs-a711.c
|
||||
@@ -0,0 +1,509 @@
|
||||
+#include <linux/wait.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/device.h>
|
||||
+#include <linux/cdev.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/poll.h>
|
||||
+#include <linux/spinlock.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/gpio/consumer.h>
|
||||
+#include <linux/regulator/consumer.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/slab.h>
|
||||
+
|
||||
+#define DRIVER_NAME "tbs_a711"
|
||||
+
|
||||
+#define A711_IOCTL_RESET _IO('A', 0)
|
||||
+#define A711_IOCTL_POWERUP _IO('A', 1)
|
||||
+#define A711_IOCTL_POWERDN _IO('A', 2)
|
||||
+#define A711_IOCTL_STATUS _IOR('A', 3, int)
|
||||
+
|
||||
+enum {
|
||||
+ A711_REQ_NONE = 0,
|
||||
+ A711_REQ_RESET,
|
||||
+ A711_REQ_PWDN,
|
||||
+ A711_REQ_PWUP,
|
||||
+};
|
||||
+
|
||||
+struct a711_dev {
|
||||
+ struct device *dev;
|
||||
+
|
||||
+ struct gpio_desc *enable_gpio;
|
||||
+ struct gpio_desc *reset_gpio;
|
||||
+ struct gpio_desc *wakeup_gpio;
|
||||
+ struct regulator *regulator;
|
||||
+ int wakeup_irq;
|
||||
+ u32 reset_duration;
|
||||
+ struct cdev cdev;
|
||||
+ dev_t major;
|
||||
+
|
||||
+ // change
|
||||
+ spinlock_t lock;
|
||||
+ wait_queue_head_t waitqueue;
|
||||
+ int got_wakeup;
|
||||
+ int is_open;
|
||||
+ struct work_struct work;
|
||||
+ int last_request;
|
||||
+ int is_enabled;
|
||||
+};
|
||||
+
|
||||
+static void a711_reset(struct a711_dev* a711)
|
||||
+{
|
||||
+ struct device *dev = a711->dev;
|
||||
+
|
||||
+ if (!a711->is_enabled)
|
||||
+ return;
|
||||
+
|
||||
+ if (!a711->reset_gpio) {
|
||||
+ dev_err(dev, "reset is not configured for this device");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ dev_info(dev, "resetting");
|
||||
+
|
||||
+ gpiod_set_value(a711->reset_gpio, 1);
|
||||
+ msleep(a711->reset_duration);
|
||||
+ gpiod_set_value(a711->reset_gpio, 0);
|
||||
+}
|
||||
+
|
||||
+static void a711_power_down(struct a711_dev* a711)
|
||||
+{
|
||||
+ struct device *dev = a711->dev;
|
||||
+
|
||||
+ if (!a711->is_enabled)
|
||||
+ return;
|
||||
+
|
||||
+ dev_info(dev, "powering down");
|
||||
+
|
||||
+ gpiod_set_value(a711->enable_gpio, 0);
|
||||
+ if (a711->regulator)
|
||||
+ regulator_disable(a711->regulator);
|
||||
+ else
|
||||
+ gpiod_set_value(a711->reset_gpio, 1);
|
||||
+ a711->is_enabled = 0;
|
||||
+}
|
||||
+
|
||||
+static void a711_power_up(struct a711_dev* a711)
|
||||
+{
|
||||
+ struct device *dev = a711->dev;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (a711->is_enabled)
|
||||
+ return;
|
||||
+
|
||||
+ dev_info(dev, "powering up");
|
||||
+
|
||||
+ // power up
|
||||
+ if (a711->regulator) {
|
||||
+ ret = regulator_enable(a711->regulator);
|
||||
+ if (ret < 0) {
|
||||
+ dev_err(dev, "can't enable power supply err=%d", ret);
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ gpiod_set_value(a711->enable_gpio, 1);
|
||||
+ gpiod_set_value(a711->reset_gpio, 1);
|
||||
+ msleep(a711->reset_duration);
|
||||
+ gpiod_set_value(a711->reset_gpio, 0);
|
||||
+ a711->is_enabled = 1;
|
||||
+}
|
||||
+
|
||||
+static struct class* a711_class;
|
||||
+
|
||||
+static void a711_work_handler(struct work_struct *work)
|
||||
+{
|
||||
+ struct a711_dev *a711 = container_of(work, struct a711_dev, work);
|
||||
+ int last_request;
|
||||
+
|
||||
+ spin_lock(&a711->lock);
|
||||
+ last_request = a711->last_request;
|
||||
+ a711->last_request = 0;
|
||||
+ spin_unlock(&a711->lock);
|
||||
+
|
||||
+ if (last_request == A711_REQ_RESET) {
|
||||
+ a711_reset(a711);
|
||||
+ } else if (last_request == A711_REQ_PWDN) {
|
||||
+ a711_power_down(a711);
|
||||
+ } else if (last_request == A711_REQ_PWUP) {
|
||||
+ a711_power_up(a711);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static bool a711_has_wakeup(struct a711_dev* a711)
|
||||
+{
|
||||
+ bool got_wakeup;
|
||||
+ spin_lock(&a711->lock);
|
||||
+ got_wakeup = a711->got_wakeup;
|
||||
+ spin_unlock(&a711->lock);
|
||||
+ return got_wakeup;
|
||||
+}
|
||||
+
|
||||
+static ssize_t a711_read(struct file *fp, char __user *buf, size_t len,
|
||||
+ loff_t *off)
|
||||
+{
|
||||
+ struct a711_dev* a711 = fp->private_data;
|
||||
+ int ret;
|
||||
+ char tmp_buf[1] = {1};
|
||||
+ int got_wakeup;
|
||||
+ int non_blocking = fp->f_flags & O_NONBLOCK;
|
||||
+
|
||||
+ // first handle non-blocking path
|
||||
+ if (non_blocking && !a711_has_wakeup(a711))
|
||||
+ return -EWOULDBLOCK;
|
||||
+
|
||||
+ // wait for availability of wakeup
|
||||
+ ret = wait_event_interruptible(a711->waitqueue,
|
||||
+ a711_has_wakeup(a711));
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ spin_lock(&a711->lock);
|
||||
+
|
||||
+ got_wakeup = a711->got_wakeup;
|
||||
+ a711->got_wakeup = 0;
|
||||
+
|
||||
+ if (!got_wakeup) {
|
||||
+ ret = -EIO;
|
||||
+ } else {
|
||||
+ if (copy_to_user(buf, tmp_buf, 1))
|
||||
+ ret = -EFAULT;
|
||||
+ else
|
||||
+ ret = 1;
|
||||
+ }
|
||||
+
|
||||
+ spin_unlock(&a711->lock);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static ssize_t a711_write(struct file *fp, const char __user *buf,
|
||||
+ size_t len, loff_t *off)
|
||||
+{
|
||||
+ struct a711_dev* a711 = fp->private_data;
|
||||
+ int ret;
|
||||
+ char tmp_buf[1];
|
||||
+ int update = 0;
|
||||
+
|
||||
+ if (len == 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ ret = copy_from_user(tmp_buf, buf, 1);
|
||||
+ if (ret)
|
||||
+ return -EFAULT;
|
||||
+
|
||||
+ spin_lock(&a711->lock);
|
||||
+
|
||||
+ switch (tmp_buf[0]) {
|
||||
+ case 'r':
|
||||
+ a711->last_request = A711_REQ_RESET;
|
||||
+ break;
|
||||
+ case 'u':
|
||||
+ a711->last_request = A711_REQ_PWUP;
|
||||
+ break;
|
||||
+ case 'd':
|
||||
+ a711->last_request = A711_REQ_PWDN;
|
||||
+ break;
|
||||
+ default:
|
||||
+ a711->last_request = A711_REQ_NONE;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ update = a711->last_request != 0;
|
||||
+
|
||||
+ spin_unlock(&a711->lock);
|
||||
+
|
||||
+ if (update)
|
||||
+ schedule_work(&a711->work);
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+static unsigned int a711_poll(struct file *fp, poll_table *wait)
|
||||
+{
|
||||
+ struct a711_dev* a711 = fp->private_data;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ poll_wait(fp, &a711->waitqueue, wait);
|
||||
+
|
||||
+ spin_lock(&a711->lock);
|
||||
+ if (a711->got_wakeup)
|
||||
+ ret |= POLLIN | POLLRDNORM;
|
||||
+ spin_unlock(&a711->lock);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static long a711_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
|
||||
+{
|
||||
+ struct a711_dev* a711 = fp->private_data;
|
||||
+ unsigned long flags;
|
||||
+ int ret = -ENOSYS;
|
||||
+ void __user *parg = (void __user *)arg;
|
||||
+ int powered;
|
||||
+
|
||||
+ if (!capable(CAP_SYS_ADMIN))
|
||||
+ return -EACCES;
|
||||
+
|
||||
+ spin_lock_irqsave(&a711->lock, flags);
|
||||
+
|
||||
+ switch (cmd) {
|
||||
+ case A711_IOCTL_RESET:
|
||||
+ a711->last_request = A711_REQ_RESET;
|
||||
+ ret = 0;
|
||||
+ break;
|
||||
+ case A711_IOCTL_POWERUP:
|
||||
+ a711->last_request = A711_REQ_PWUP;
|
||||
+ ret = 0;
|
||||
+ break;
|
||||
+ case A711_IOCTL_POWERDN:
|
||||
+ a711->last_request = A711_REQ_PWDN;
|
||||
+ ret = 0;
|
||||
+ break;
|
||||
+ case A711_IOCTL_STATUS:
|
||||
+ powered = a711->is_enabled || a711->last_request == A711_REQ_PWUP;
|
||||
+ spin_unlock_irqrestore(&a711->lock, flags);
|
||||
+
|
||||
+ if (copy_to_user(parg, &powered, sizeof powered))
|
||||
+ return -EFAULT;
|
||||
+
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ spin_unlock_irqrestore(&a711->lock, flags);
|
||||
+
|
||||
+ if (ret == 0)
|
||||
+ schedule_work(&a711->work);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int a711_release(struct inode *ip, struct file *fp)
|
||||
+{
|
||||
+ struct a711_dev* a711 = fp->private_data;
|
||||
+
|
||||
+ spin_lock(&a711->lock);
|
||||
+ a711->is_open = 0;
|
||||
+ spin_unlock(&a711->lock);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int a711_open(struct inode *ip, struct file *fp)
|
||||
+{
|
||||
+ struct a711_dev* a711 = container_of(ip->i_cdev, struct a711_dev, cdev);
|
||||
+
|
||||
+ fp->private_data = a711;
|
||||
+
|
||||
+ spin_lock(&a711->lock);
|
||||
+ if (a711->is_open) {
|
||||
+ spin_unlock(&a711->lock);
|
||||
+ return -EBUSY;
|
||||
+ }
|
||||
+
|
||||
+ a711->is_open = 1;
|
||||
+ spin_unlock(&a711->lock);
|
||||
+
|
||||
+ nonseekable_open(ip, fp);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct file_operations a711_fops = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .read = a711_read,
|
||||
+ .write = a711_write,
|
||||
+ .poll = a711_poll,
|
||||
+ .unlocked_ioctl = a711_ioctl,
|
||||
+ .open = a711_open,
|
||||
+ .release = a711_release,
|
||||
+ .llseek = noop_llseek,
|
||||
+};
|
||||
+
|
||||
+static irqreturn_t a711_wakeup_isr(int irq, void *dev_id)
|
||||
+{
|
||||
+ struct a711_dev *a711 = dev_id;
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ spin_lock_irqsave(&a711->lock, flags);
|
||||
+ a711->got_wakeup = 1;
|
||||
+ spin_unlock_irqrestore(&a711->lock, flags);
|
||||
+
|
||||
+ wake_up_interruptible(&a711->waitqueue);
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static int a711_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct a711_dev *a711;
|
||||
+ struct device *dev = &pdev->dev;
|
||||
+ struct device_node *np = dev->of_node;
|
||||
+ struct device *sdev;
|
||||
+ const char* cdev_name = NULL;
|
||||
+ int ret;
|
||||
+
|
||||
+ a711 = devm_kzalloc(dev, sizeof(*a711), GFP_KERNEL);
|
||||
+ if (!a711)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ a711->dev = dev;
|
||||
+ platform_set_drvdata(pdev, a711);
|
||||
+ init_waitqueue_head(&a711->waitqueue);
|
||||
+ spin_lock_init(&a711->lock);
|
||||
+ INIT_WORK(&a711->work, &a711_work_handler);
|
||||
+
|
||||
+ // get device name and reset time from device tree
|
||||
+ ret = of_property_read_u32_index(np, "reset-duration-ms", 0,
|
||||
+ &a711->reset_duration);
|
||||
+ if (ret) {
|
||||
+ a711->reset_duration = 10;
|
||||
+ }
|
||||
+
|
||||
+ ret = of_property_read_string(np, "char-device-name", &cdev_name);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "char-device-name is not configured");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ a711->enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_HIGH);
|
||||
+ if (IS_ERR(a711->enable_gpio)) {
|
||||
+ dev_err(dev, "can't get enable gpio err=%ld",
|
||||
+ PTR_ERR(a711->enable_gpio));
|
||||
+ return PTR_ERR(a711->enable_gpio);
|
||||
+ }
|
||||
+
|
||||
+ a711->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
|
||||
+ if (IS_ERR(a711->reset_gpio)) {
|
||||
+ dev_err(dev, "can't get reset gpio err=%ld",
|
||||
+ PTR_ERR(a711->reset_gpio));
|
||||
+ return PTR_ERR(a711->reset_gpio);
|
||||
+ }
|
||||
+
|
||||
+ a711->wakeup_gpio = devm_gpiod_get_optional(dev, "wakeup", GPIOD_IN);
|
||||
+ if (IS_ERR(a711->wakeup_gpio)) {
|
||||
+ dev_err(dev, "can't get wakeup gpio err=%ld",
|
||||
+ PTR_ERR(a711->wakeup_gpio));
|
||||
+ return PTR_ERR(a711->wakeup_gpio);
|
||||
+ }
|
||||
+
|
||||
+ a711->wakeup_irq = gpiod_to_irq(a711->wakeup_gpio);
|
||||
+ if (a711->wakeup_irq > 0) {
|
||||
+ ret = devm_request_irq(dev, a711->wakeup_irq,
|
||||
+ a711_wakeup_isr,
|
||||
+ IRQF_TRIGGER_RISING |
|
||||
+ IRQF_TRIGGER_FALLING,
|
||||
+ "a711-wakeup", a711);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "error requesting wakeup-irq: %d", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ a711->regulator = devm_regulator_get_optional(dev, "power");
|
||||
+ if (IS_ERR(a711->regulator)) {
|
||||
+ ret = PTR_ERR(a711->regulator);
|
||||
+ if (ret != -ENODEV) {
|
||||
+ dev_err(dev, "can't get power supply err=%d", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ a711->regulator = NULL;
|
||||
+ }
|
||||
+
|
||||
+ // create char device
|
||||
+ ret = alloc_chrdev_region(&a711->major, 0, 1, "a711");
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "can't allocate chrdev region");
|
||||
+ goto err_disable_regulator;
|
||||
+ }
|
||||
+
|
||||
+ cdev_init(&a711->cdev, &a711_fops);
|
||||
+ a711->cdev.owner = THIS_MODULE;
|
||||
+ ret = cdev_add(&a711->cdev, a711->major, 1);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "can't add cdev");
|
||||
+ goto err_unreg_chrev_region;
|
||||
+ }
|
||||
+
|
||||
+ sdev = device_create(a711_class, dev, a711->major, a711, cdev_name);
|
||||
+ if (IS_ERR(sdev)) {
|
||||
+ ret = PTR_ERR(sdev);
|
||||
+ goto err_del_cdev;
|
||||
+ }
|
||||
+
|
||||
+ gpiod_set_value(a711->enable_gpio, 0);
|
||||
+ if (!a711->regulator)
|
||||
+ gpiod_set_value(a711->reset_gpio, 1);
|
||||
+
|
||||
+ dev_info(dev, "initialized TBS A711 platform driver");
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_del_cdev:
|
||||
+ cdev_del(&a711->cdev);
|
||||
+err_unreg_chrev_region:
|
||||
+ unregister_chrdev(a711->major, "a711");
|
||||
+err_disable_regulator:
|
||||
+ cancel_work_sync(&a711->work);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int a711_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct a711_dev *a711 = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ a711_power_down(a711);
|
||||
+
|
||||
+ cancel_work_sync(&a711->work);
|
||||
+
|
||||
+ device_destroy(a711_class, a711->major);
|
||||
+ cdev_del(&a711->cdev);
|
||||
+ unregister_chrdev(a711->major, "a711");
|
||||
+
|
||||
+ if (a711->wakeup_irq > 0)
|
||||
+ devm_free_irq(a711->dev, a711->wakeup_irq, a711);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id a711_of_match[] = {
|
||||
+ { .compatible = "custom,power-manager" },
|
||||
+ {},
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, a711_of_match);
|
||||
+
|
||||
+static struct platform_driver a711_platform_driver = {
|
||||
+ .probe = a711_probe,
|
||||
+ .remove = a711_remove,
|
||||
+ .driver = {
|
||||
+ .name = DRIVER_NAME,
|
||||
+ .of_match_table = a711_of_match,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int __init a711_driver_init(void)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ a711_class = class_create(THIS_MODULE, "a711");
|
||||
+
|
||||
+ ret = platform_driver_register(&a711_platform_driver);
|
||||
+ if (ret)
|
||||
+ class_destroy(a711_class);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void __exit a711_driver_exit(void)
|
||||
+{
|
||||
+ platform_driver_unregister(&a711_platform_driver);
|
||||
+ class_destroy(a711_class);
|
||||
+}
|
||||
+
|
||||
+module_init(a711_driver_init);
|
||||
+module_exit(a711_driver_exit);
|
||||
+
|
||||
+MODULE_VERSION("1.0.0");
|
||||
+MODULE_DESCRIPTION("TBS A711 Tablet Platform Driver");
|
||||
+MODULE_AUTHOR("Ondrej Jirman <megous@megous.com>");
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
From 1b732183172780283b7311bf0959b7ba7d4a4153 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Fri, 10 Nov 2017 22:21:29 +0100
|
||||
Subject: [PATCH 49/82] ARM: dts: sun8i-a83t: Add uart2-uart4
|
||||
|
||||
Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
---
|
||||
arch/arm/boot/dts/sun8i-a83t.dtsi | 33 +++++++++++++++++++++++++++++++
|
||||
1 file changed, 33 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi
|
||||
index d9074f050a9c..788ecf540f55 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-a83t.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
|
||||
@@ -880,6 +880,39 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
+ uart2: serial@01c28800 {
|
||||
+ compatible = "snps,dw-apb-uart";
|
||||
+ reg = <0x01c28800 0x400>;
|
||||
+ interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ reg-shift = <2>;
|
||||
+ reg-io-width = <4>;
|
||||
+ clocks = <&ccu CLK_BUS_UART2>;
|
||||
+ resets = <&ccu RST_BUS_UART2>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ uart3: serial@01c28c00 {
|
||||
+ compatible = "snps,dw-apb-uart";
|
||||
+ reg = <0x01c28c00 0x400>;
|
||||
+ interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ reg-shift = <2>;
|
||||
+ reg-io-width = <4>;
|
||||
+ clocks = <&ccu CLK_BUS_UART3>;
|
||||
+ resets = <&ccu RST_BUS_UART3>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ uart4: serial@01c29000 {
|
||||
+ compatible = "snps,dw-apb-uart";
|
||||
+ reg = <0x01c29000 0x400>;
|
||||
+ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
|
||||
+ reg-shift = <2>;
|
||||
+ reg-io-width = <4>;
|
||||
+ clocks = <&ccu CLK_BUS_UART4>;
|
||||
+ resets = <&ccu RST_BUS_UART4>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
i2c0: i2c@1c2ac00 {
|
||||
compatible = "allwinner,sun8i-a83t-i2c",
|
||||
"allwinner,sun6i-a31-i2c";
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
From 8921a3bf53f233c746f591c58b2840963cee88a2 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Fri, 10 Nov 2017 22:22:44 +0100
|
||||
Subject: [PATCH 50/82] ARM: dts: sun8i-a83t: Add uart2 PB pins
|
||||
|
||||
These are used on TBS A83T A711 tablet for GPS serial port.
|
||||
|
||||
Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
---
|
||||
arch/arm/boot/dts/sun8i-a83t.dtsi | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi
|
||||
index 788ecf540f55..a8ff7a8efe71 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-a83t.dtsi
|
||||
+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
|
||||
@@ -775,6 +775,11 @@
|
||||
pins = "PG8", "PG9";
|
||||
function = "uart1";
|
||||
};
|
||||
+
|
||||
+ uart2_pb_pins: uart2-pb-pins {
|
||||
+ pins = "PB0", "PB1";
|
||||
+ function = "uart2";
|
||||
+ };
|
||||
};
|
||||
|
||||
timer@1c20c00 {
|
||||
--
|
||||
2.20.1
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
From 9e45d6dd4dfcc8706081ee992b24acab372d845a Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Jirman <megous@megous.com>
|
||||
Date: Fri, 10 Nov 2017 22:24:15 +0100
|
||||
Subject: [PATCH 51/82] ARM: dts: sun8i-a83t-tbs-a711: Enable uart2 and add gps
|
||||
regulator
|
||||
|
||||
Now we can use tbs-a711 driver for power/reset control for GPS module.
|
||||
Enable this. This allows access to u-blox NEO-6M connected to uart2.
|
||||
|
||||
Signed-off-by: Ondrej Jirman <megous@megous.com>
|
||||
---
|
||||
arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts | 23 +++++++++++++++++++++++
|
||||
1 file changed, 23 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
index ab4dce4b1e67..b0a94cf13740 100644
|
||||
--- a/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
+++ b/arch/arm/boot/dts/sun8i-a83t-tbs-a711.dts
|
||||
@@ -121,6 +121,15 @@
|
||||
};
|
||||
};
|
||||
|
||||
+ reg_gps: reg-gps {
|
||||
+ compatible = "regulator-fixed";
|
||||
+ regulator-name = "gps";
|
||||
+ regulator-min-microvolt = <3000000>;
|
||||
+ regulator-max-microvolt = <3000000>;
|
||||
+ enable-active-high;
|
||||
+ gpio = <&pio 3 4 GPIO_ACTIVE_HIGH>; /* PD4 */
|
||||
+ };
|
||||
+
|
||||
reg_vbat: reg-vbat {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "vbat";
|
||||
@@ -149,6 +158,13 @@
|
||||
clocks = <&ac100_rtc 1>;
|
||||
clock-names = "ext_clock";
|
||||
};
|
||||
+
|
||||
+ gps {
|
||||
+ compatible = "custom,power-manager";
|
||||
+ power-supply = <®_gps>;
|
||||
+ reset-duration-ms = <5>;
|
||||
+ char-device-name = "pwr-gps";
|
||||
+ };
|
||||
};
|
||||
|
||||
&cpu0 {
|
||||
@@ -564,6 +580,13 @@
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
+/* GPS NEO-6M */
|
||||
+&uart2 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&uart2_pb_pins>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&usb_otg {
|
||||
dr_mode = "otg";
|
||||
status = "okay";
|
||||
--
|
||||
2.20.1
|
||||
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue