Commit fc0f2d21 authored by Martin Kepplinger's avatar Martin Kepplinger
Browse files

Merge branch '5.13.1/librem5_misc' into 5.13.1/librem5__integration_byzantium

parents 66e914c0 973098d1
......@@ -18,6 +18,8 @@ Required properties:
Optional properties:
- enable-gpios : gpio pin to enable/disable the device.
- vled-supply : LED supply
- ti,brightness-mapping-exponential: Whether to use exponential
brightness mapping
- ti,ovp-microvolt: Overvoltage protection in
micro-volt, can be 17000000, 21000000, 25000000 or
29000000. If ti,ovp-microvolt is not specified it
......@@ -51,6 +53,7 @@ led-controller@36 {
enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
vled-supply = <&vbatt>;
ti,ovp-microvolt = <29000000>;
ti,brightness-mapping-exponential;
led@0 {
reg = <0>;
......
......@@ -12,12 +12,6 @@ / {
compatible = "purism,librem5r2", "purism,librem5", "fsl,imx8mq";
};
&bq25895 {
ti,battery-regulation-voltage = <4192000>; /* uV */
ti,charge-current = <1600000>; /* uA */
ti,termination-current = <66000>; /* uA */
};
&accel_gyro {
mount-matrix = "1", "0", "0",
"0", "-1", "0",
......@@ -52,6 +46,14 @@ camera2_ep: endpoint {
};
};
&bat {
maxim,battery-capacity = <2000000>; /* uAh */
};
&bq25895 {
ti,charge-current = <1600000>; /* uA */
};
&proximity {
proximity-near-level = <120>;
};
......@@ -11,6 +11,7 @@ / {
};
&bat {
maxim,battery-capacity = <4200000>; /* uAh */
maxim,rsns-microohm = <1667>;
};
......
......@@ -7,8 +7,10 @@
#include "dt-bindings/input/input.h"
#include <dt-bindings/interrupt-controller/irq.h>
#include "dt-bindings/leds/common.h"
#include "dt-bindings/pwm/pwm.h"
#include "dt-bindings/usb/pd.h"
#include "dt-bindings/rfkill/rfkill.h"
#include "imx8mq.dtsi"
/ {
......@@ -36,7 +38,7 @@ chosen {
gpio-keys {
compatible = "gpio-keys";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_keys>, <&pinctrl_hsw>;
pinctrl-0 = <&pinctrl_keys>;
vol-down {
label = "VOL_DOWN";
......@@ -77,11 +79,10 @@ red {
leds {
compatible = "gpio-leds";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_flash>, <&pinctrl_hub_nreset>,
pinctrl-0 = <&pinctrl_hub_nreset>,
<&pinctrl_sd_pwr>, <&pinctrl_charger>
, <&pinctrl_smc>,
<&pinctrl_gnss>,
<&pinctrl_flash_pwr>,
<&pinctrl_wwan_pwr>,
<&pinctrl_wwan>;
......@@ -98,13 +99,6 @@ flash-strobe {
linux,default-trigger = "flash";
};
flash-strobe {
label = "flash_strobe";
gpios = <&gpio1 21 GPIO_ACTIVE_HIGH>;
default-state = "off";
linux,default-trigger = "flash";
};
hub-nreset {
label = "hub_nreset";
gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>;
......@@ -117,12 +111,6 @@ sd-en {
default-state = "on";
};
flash-en {
label = "flash_en";
gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>;
default-state = "off";
};
gnss-nreset {
label = "gnss_nreset";
gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
......@@ -303,6 +291,30 @@ reg_wifi_3v3: regulator-wifi-3v3 {
regulator-always-on;
};
rfkill-hks {
compatible = "rfkill-hks";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_hsw>;
mic-hks {
gpios = <&gpio4 1 GPIO_ACTIVE_LOW>;
name = "mic-hks";
type = <RFKILL_MIC>;
};
wlan-hks {
gpios = <&gpio4 10 GPIO_ACTIVE_LOW>;
name = "wlan-hks";
type = <RFKILL_WLAN>;
};
wwan-hks {
gpios = <&gpio4 0 GPIO_ACTIVE_LOW>;
name = "wwan-hks";
type = <RFKILL_WWAN>;
};
};
sound {
compatible = "simple-audio-card";
pinctrl-names = "default";
......@@ -596,11 +608,6 @@ pinctrl_flash: flashgrp {
fsl,pins = <
/* FLASH_STROBE */
MX8MQ_IOMUXC_ENET_TD0_GPIO1_IO21 0x83
>;
};
pinctrl_flash_pwr: flashpwrgrp {
fsl,pins = <
/* FLASH_EN */
MX8MQ_IOMUXC_ENET_TXC_GPIO1_IO23 0x83
>;
......@@ -1254,25 +1261,24 @@ reg_lcd_avee: outn {
};
flash@53 {
compatible = "lm3560";
reg = <0x53>; /* A6 ?? */
compatible = "ti,lm3560";
pinctrl-0 = <&pinctrl_flash>;
pinctrl-names = "default";
#address-cells = <1>;
#size-cells = <0>;
flash@0 {
reg = <0x0>;
flash-timeout-us = <150000>;
flash-max-microamp = <320000>;
led-max-microamp = <60000>;
label = "lm3560:flash";
};
torch@1 {
reg = <0x1>;
led-max-microamp = <10000>;
label = "lm3560:torch";
reg = <0x53>;
enable-gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>;
/* TODO */
//strobe-gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
vin-supply = <&reg_vsys_3v4>;
torch: led@0 {
reg = <1>;
function = LED_FUNCTION_TORCH;
color = <LED_COLOR_ID_WHITE>;
led-max-microamp = <93750>;
flash-max-microamp = <875000>;
flash-max-timeout-us = <1024000>;
};
};
proximity: prox@60 {
......@@ -1431,6 +1437,7 @@ bat: fuel-gauge@36 {
maxim,over-heat-temp = <700>;
maxim,over-volt = <4500>;
maxim,rsns-microohm = <5000>;
maxim,termination-current = <160000>;
maxim,vchg-4V2;
};
......@@ -1442,12 +1449,15 @@ bq25895: charger@6a {
interrupt-parent = <&gpio3>;
interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
phys = <&usb3_phy0>;
ti,precharge-current = <130000>; /* uA */
ti,battery-regulation-voltage = <4208000>; /* uV */
ti,termination-current = <128000>; /* uA */
ti,precharge-current = <128000>; /* uA */
ti,minimum-sys-voltage = <3700000>; /* uV */
ti,boost-voltage = <5000000>; /* uV */
ti,boost-max-current = <500000>; /* uA */
ti,boost-max-current = <1500000>; /* uA */
ti,use-vinmin-threshold = <1>; /* enable VINDPM */
ti,vinmin-threshold = <3900000>; /* uV */
ti,auto_dpdm_disable;
monitored-battery = <&bat>;
power-supplies = <&typec_pd>;
otg-gpios = <&gpio3 4 GPIO_ACTIVE_HIGH>;
......
......@@ -342,7 +342,7 @@ timer {
};
soc@0 {
compatible = "fsl,imx8mq-soc", "simple-bus";
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x0 0x0 0x0 0x3e000000>;
......
......@@ -254,6 +254,7 @@ CONFIG_MAC80211_LEDS=y
CONFIG_MAC80211_DEBUGFS=y
CONFIG_RFKILL=m
CONFIG_RFKILL_GPIO=m
CONFIG_RFKILL_HKS=m
CONFIG_NET_9P=y
CONFIG_NET_9P_VIRTIO=y
CONFIG_FAILOVER=y
......@@ -815,10 +816,12 @@ CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_MMC_SDHCI_ESDHC_IMX=y
CONFIG_MMC_SPI=y
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_CLASS_FLASH=y
CONFIG_LEDS_LM3692X=y
CONFIG_LEDS_GPIO=y
CONFIG_LEDS_PWM=y
CONFIG_LEDS_SYSCON=y
CONFIG_LEDS_LM3560=m
CONFIG_LEDS_TRIGGER_TIMER=m
CONFIG_LEDS_TRIGGER_ONESHOT=m
CONFIG_LEDS_TRIGGER_DISK=y
......
......@@ -448,7 +448,7 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
/* BUS */
hws[IMX8MQ_CLK_MAIN_AXI] = imx8m_clk_hw_composite_bus_critical("main_axi", imx8mq_main_axi_sels, base + 0x8800);
hws[IMX8MQ_CLK_ENET_AXI] = imx8m_clk_hw_composite_bus("enet_axi", imx8mq_enet_axi_sels, base + 0x8880);
hws[IMX8MQ_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite_bus("nand_usdhc_bus", imx8mq_nand_usdhc_sels, base + 0x8900);
hws[IMX8MQ_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite_critical("nand_usdhc_bus", imx8mq_nand_usdhc_sels, base + 0x8900);
hws[IMX8MQ_CLK_VPU_BUS] = imx8m_clk_hw_composite_bus("vpu_bus", imx8mq_vpu_bus_sels, base + 0x8980);
hws[IMX8MQ_CLK_DISP_AXI] = imx8m_clk_hw_composite_bus("disp_axi", imx8mq_disp_axi_sels, base + 0x8a00);
hws[IMX8MQ_CLK_DISP_APB] = imx8m_clk_hw_composite_bus("disp_apb", imx8mq_disp_apb_sels, base + 0x8a80);
......
......@@ -1815,7 +1815,7 @@ static int etnaviv_gpu_platform_probe(struct platform_device *pdev)
* yet been performed to determine an appropriate value.
*/
pm_runtime_use_autosuspend(gpu->dev);
pm_runtime_set_autosuspend_delay(gpu->dev, 200);
pm_runtime_set_autosuspend_delay(gpu->dev, 50);
pm_runtime_enable(gpu->dev);
err = component_add(&pdev->dev, &gpu_ops);
......
......@@ -13,6 +13,8 @@
* http://www.glyn.com/Products/Displays
*/
#define DEBUG
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
......@@ -52,6 +54,8 @@
#define EV_REGISTER_OFFSET_Y 0x45
#define EV_REGISTER_OFFSET_X 0x46
#define REG_FW_VERSION 0xa6
#define NO_REGISTER 0xff
#define WORK_REGISTER_OPMODE 0x3c
......@@ -227,6 +231,13 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
if (error) {
dev_err_ratelimited(dev, "Unable to fetch data, error: %d\n",
error);
// HACK: empty all slots on error
for (i = 0; i < tsdata->max_support_points; i++) {
input_mt_slot(tsdata->input, i);
input_mt_report_slot_state(tsdata->input, MT_TOOL_FINGER,
false);
}
input_sync(tsdata->input);
goto out;
}
......@@ -697,6 +708,26 @@ static int edt_ft5x06_debugfs_mode_set(void *data, u64 mode)
DEFINE_SIMPLE_ATTRIBUTE(debugfs_mode_fops, edt_ft5x06_debugfs_mode_get,
edt_ft5x06_debugfs_mode_set, "%llu\n");
static int edt_ft5x06_debugfs_fw_version_get(void *data, u64 *version)
{
struct edt_ft5x06_ts_data *tsdata = data;
struct i2c_client *client = tsdata->client;
mutex_lock(&tsdata->mutex);
*version = edt_ft5x06_register_read(tsdata, REG_FW_VERSION);
if (*version == 0xff || *version == 0x00)
dev_warn(&client->dev, "failed to get firmware version\n");
mutex_unlock(&tsdata->mutex);
return 0;
};
DEFINE_SIMPLE_ATTRIBUTE(debugfs_fw_version_fops,
edt_ft5x06_debugfs_fw_version_get,
NULL, "%llu\n");
static ssize_t edt_ft5x06_debugfs_raw_data_read(struct file *file,
char __user *buf, size_t count, loff_t *off)
{
......@@ -790,6 +821,9 @@ static void edt_ft5x06_ts_prepare_debugfs(struct edt_ft5x06_ts_data *tsdata,
debugfs_create_file("mode", S_IRUSR | S_IWUSR,
tsdata->debug_dir, tsdata, &debugfs_mode_fops);
debugfs_create_file("fw_version", S_IRUSR,
tsdata->debug_dir, tsdata,
&debugfs_fw_version_fops);
debugfs_create_file("raw_data", S_IRUSR,
tsdata->debug_dir, tsdata, &debugfs_raw_data_fops);
}
......@@ -925,6 +959,9 @@ static int edt_ft5x06_ts_identify(struct i2c_client *client,
snprintf(model_name, EDT_NAME_LEN,
"EVERVISION-FT5726NEi");
break;
case 0x02: /* FT 8506 */
snprintf(model_name, EDT_NAME_LEN, "Focaltec FT8006P");
break;
default:
snprintf(model_name, EDT_NAME_LEN,
"generic ft5x06 (%02x)",
......@@ -1069,6 +1106,8 @@ static void edt_ft5x06_disable_regulator(void *arg)
regulator_disable(data->vcc);
}
bool mantix_panel_prepared(void);
static int edt_ft5x06_ts_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
......@@ -1080,6 +1119,12 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
int error;
char fw_version[EDT_NAME_LEN];
/* Since the panel handles the reset via gpio we need to wait until the panel is up */
if (!mantix_panel_prepared()) {
dev_dbg(&client->dev, "Panel not yet ready\n");
return -EPROBE_DEFER;
}
dev_dbg(&client->dev, "probing for EDT FT5x06 I2C\n");
tsdata = devm_kzalloc(&client->dev, sizeof(*tsdata), GFP_KERNEL);
......@@ -1220,6 +1265,7 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
error = devm_request_threaded_irq(&client->dev, client->irq,
NULL, edt_ft5x06_ts_isr, irq_flags,
client->name, tsdata);
if (error) {
dev_err(&client->dev, "Unable to request touchscreen IRQ.\n");
return error;
......
......@@ -876,6 +876,18 @@ config LEDS_TI_LMU_COMMON
This supports common features between the TI LM3532, LM3631, LM3632,
LM3633, LM3695 and LM3697.
config LEDS_LM3560
tristate "LED driver for LM3560"
depends on LEDS_CLASS && I2C && OF
depends on LEDS_CLASS_FLASH
select REGMAP_I2C
help
Say Y to enable support for the LM3560 LED flash driver.
The driver support flash and torch mode.
To compile this driver as a module, choose M here: the module
will be called leds-led3560.
config LEDS_LM3697
tristate "LED driver for LM3697"
depends on LEDS_TI_LMU_COMMON
......
......@@ -42,6 +42,7 @@ obj-$(CONFIG_LEDS_LM3530) += leds-lm3530.o
obj-$(CONFIG_LEDS_LM3532) += leds-lm3532.o
obj-$(CONFIG_LEDS_LM3533) += leds-lm3533.o
obj-$(CONFIG_LEDS_LM355x) += leds-lm355x.o
obj-$(CONFIG_LEDS_LM3560) += leds-lm3560.o
obj-$(CONFIG_LEDS_LM3601X) += leds-lm3601x.o
obj-$(CONFIG_LEDS_LM36274) += leds-lm36274.o
obj-$(CONFIG_LEDS_LM3642) += leds-lm3642.o
......
// SPDX-License-Identifier: PL-2.0
// TI LM3560 LED driver
// Copyright (C) 2020 Purism SPC
// http://www.ti.com/lit/ds/symlink/lm3560.pdf
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/led-class-flash.h>
#include <linux/leds.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#define LM3560_NAME "lm3560-led"
#define LM3560_ENABLE_REG 0x10
#define LM3560_ENABLE_MASK GENMASK(1, 0)
#define LM3560_ENABLE_LED1_FLAG BIT(3)
#define LM3560_ENABLE_LED2_FLAG BIT(4)
#define LM3560_PRIVACY_REG 0x11
#define LM3560_PRIVACY_BRIGHT_MASK GENMASK(3, 0)
#define LM3560_PRIVACY_BRIGHT_SHIFT 3
#define LM3560_INDICATOR_REG 0x12
#define LM3560_INDICATOR_BLK_REG 0x13
#define LM3560_PRIVACY_PWM_REG 0x14
#define LM3560_GPIO_REG 0x20
#define LM3560_V_LED_MONITOR_REG 0x30
#define LM3560_ADC_DELAY_REG 0x31
#define LM3560_V_IN_MONITOR_REG 0x80
#define LM3560_LAST_FLASH_REG 0x81
#define LM3560_TORCH_BRIGHT_REG 0xA0
#define LM3560_TORCH_BRIGHT_LED1_MASK GENMASK(2, 0)
#define LM3560_TORCH_BRIGHT_LED1_SHIFT 0
#define LM3560_TORCH_BRIGHT_LED2_MASK GENMASK(5, 3)
#define LM3560_TORCH_BRIGHT_LED2_SHIFT 3
#define LM3560_TORCH_BRIGHT_MIN_uA 31250
#define LM3560_TORCH_BRIGHT_STEP_uA 31250
#define LM3560_FLASH_BRIGHT_REG 0xB0
#define LM3560_FLASH_BRIGHT_LED1_MASK GENMASK(3, 0)
#define LM3560_FLASH_BRIGHT_LED1_SHIFT 0
#define LM3560_FLASH_BRIGHT_LED2_MASK GENMASK(7, 4)
#define LM3560_FLASH_BRIGHT_LED2_SHIFT 4
#define LM3560_FLASH_BRIGHT_MIN_uA 62500
#define LM3560_FLASH_BRIGHT_STEP_uA 62500
#define LM3560_FLASH_BRIGHT_DEFAULT 825000
#define LM3560_FLASH_DURATION_REG 0xC0
#define LM3560_FLASH_TIMEOUT_MASK GENMASK(4, 0)
#define LM3560_FLASH_TIMEOUT_MIN_us 32000
#define LM3560_FLASH_TIMEOUT_MAX_us 1024000
#define LM3560_FLASH_TIMEOUT_STEP_us 32000
#define LM3560_FLASH_TIMEOUT_DEFAULT_us 512000
#define LM3560_FLAGS_REG 0xD0
#define LM3560_FLAGS_TIMEOUT BIT(0)
#define LM3560_FLAGS_HOT_FLAG BIT(1)
#define LM3560_FLAGS_LED_FAILED_FLAG BIT(2)
#define LM3560_CONF1_REG 0xE0
#define LM3560_CONF2_REG 0xF0
enum lm3560_enable {
LM3560_ENABLE_SHUTDOWN = 0,
LM3560_ENABLE_PRIV_INDICATOR = BIT(0),
LM3560_ENABLE_TORCH = BIT(1),
LM3560_ENABLE_FLASH = BIT(0) | BIT(1),
};
struct lm3560_data {
struct led_classdev_flash fled_cdev;
struct i2c_client *client;
struct regmap *regmap;
struct gpio_desc *enable_gpio;
struct regulator *regulator;
unsigned int last_flag;
unsigned int flash_timeout;
u32 torch_current_max;
u32 flash_current_max;
u32 flash_timeout_max;
struct mutex lock;
};
static const struct reg_default lm3560_reg_defaults[] = {
{LM3560_ENABLE_REG, 0x18},
{LM3560_PRIVACY_REG, 0x58},
{LM3560_INDICATOR_REG, 0x00},
{LM3560_INDICATOR_BLK_REG, 0x00},
{LM3560_PRIVACY_PWM_REG, 0xF8},
{LM3560_GPIO_REG, 0x80},
{LM3560_V_LED_MONITOR_REG, 0x80},
{LM3560_ADC_DELAY_REG, 0x90},
{LM3560_V_IN_MONITOR_REG, 0xC0},
{LM3560_LAST_FLASH_REG, 0x00},
{LM3560_TORCH_BRIGHT_REG, 0x52},
{LM3560_FLASH_BRIGHT_REG, 0xDD},
{LM3560_FLASH_DURATION_REG, 0xEF},
{LM3560_FLAGS_REG, 0x00},
{LM3560_CONF1_REG, 0x6B},
{LM3560_CONF2_REG, 0xE0}
};
static bool lm3560_volatile_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
case LM3560_FLAGS_REG:
return true;
default:
return false;
}
}
static const struct regmap_config lm3560_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = LM3560_CONF2_REG,
.reg_defaults = lm3560_reg_defaults,
.num_reg_defaults = ARRAY_SIZE(lm3560_reg_defaults),
.cache_type = REGCACHE_FLAT,
.volatile_reg = lm3560_volatile_reg,
};
static struct lm3560_data *fled_cdev_to_led(struct led_classdev_flash *fled_cdev)
{
return container_of(fled_cdev, struct lm3560_data, fled_cdev);
}
static int lm3560_read_faults(struct lm3560_data *priv)
{
int flags_val;
int ret;
ret = regmap_read(priv->regmap, LM3560_FLAGS_REG, &flags_val);
if (ret < 0) {
dev_err(&priv->client->dev, "Error reading flags\n");
return -EIO;
}
priv->last_flag = 0;
if (flags_val & LM3560_FLAGS_TIMEOUT)
priv->last_flag |= LED_FAULT_TIMEOUT;
if (flags_val & LM3560_FLAGS_HOT_FLAG)
priv->last_flag |= LED_FAULT_OVER_TEMPERATURE;
if (flags_val & LM3560_FLAGS_LED_FAILED_FLAG)
priv->last_flag |= LED_FAULT_SHORT_CIRCUIT;
return priv->last_flag;
}
static int lm3560_chip_init(struct lm3560_data *priv)
{
int ret;
unsigned int flags;
if (priv->regulator) {
ret = regulator_enable(priv->regulator);
if (ret) {
dev_err(&priv->client->dev,
"failed to enable regulator: %d\n", ret);
return ret;
}
}
if (priv->enable_gpio)
gpiod_direction_output(priv->enable_gpio, 1);
mutex_lock(&priv->lock);
ret = regmap_read(priv->regmap, LM3560_FLAGS_REG, &flags);
if (ret < 0) {
dev_err(&priv->client->dev, "Failed to read flags register\n");
goto out;
}
ret = lm3560_read_faults(priv);
if (ret < 0) {
dev_err(&priv->client->dev, "Fault detected: 0x%x\n", ret);
goto out;
}
out:
mutex_unlock(&priv->lock);
return ret;
}
static int lm3560_brightness_set(struct led_classdev *cdev, enum led_brightness brightness)
{
struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(cdev);
struct lm3560_data *priv = fled_cdev_to_led(fled_cdev);
int ret;
mutex_lock(&priv->lock);
ret = lm3560_read_faults(priv);
if (ret < 0)
goto out;
if (brightness == LED_OFF) {