- New Drivers
- Add support for RAVE Supervisory Processor - (Re)moved drivers - Move Realtek Card Reader Driver to Misc - New Device Support - Add support for Pinctrl to axp20x - New Functionality - Add resume support; atmel-flexcom - Fix-ups - Split MFD (mfd) and userspace handlers (platform); cros_ec - Fix trivial (whitespace, spelling) issue(s); pcf50633-core - Clean-up error handling; ab8500-debugfs - General tidying up; tmio_core - Kconfig fix-ups; qcom-pm8xxx - Licensing changes (SPDX); stm32-lptimer, stm32-timers - Device Tree fixups; mc13xxx - Simplify/remove unused code; cros_ec_spi, axp20x, ti_am335x_tscadc, kempld-core, intel_soc_pmic_core.c, ab8500-debugfs -----BEGIN PGP SIGNATURE----- iQIcBAABCAAGBQJaYK9SAAoJEFGvii+H/HdhTBwP/iQYlVikcs728oQqYhPKcafc cH8OxA6mPoD8BDvJkfjyQ/VXFo+OHZQxs7arUYMBpHweqhRGID/uDJItkZ05O7RI 0AJoqedczfgQzmEFvos4lpnm2kIdxXZstFqQBA0vLqvbOVd8U+LUiQ/2ilOELxa/ AYUiIKO/gY0jw/1cXkYWMbLI8Z14u04OFrUzFIu8M6KSdMKyQ5RLvSAISL4l/oyO fWvYL8ngdmC7BOw0OF7kc5S5KaevP0qZ9kBNb1e0Y1gbmm1b8WhH5eaAcuWD3tR3 mxa/lQNVLIDfp1XQzTEVbWFmaic5+i4c05WrVbqZ7Q8jgQGrXtwmdcqYc6ifQJoT 1/3IH7YTYV9+k/B5cSP9m+CCY4BsNjnqXcIW1A0FLJkmCLfU8jvMBBaapXVZk23h rgpRYEWRSVGQEa2E/9tDSndpqUcllWriSKYcTtNGX65kIiP1+VQYpUps/Ff7X8bj CiPGIGP4jYywk4SAlTjs0Dothh/g3+4CtyMK4ARei9z1P5prKuPMHyG6Xf0PtTMv qLD+0vplL2AbpdlpH8U1Eqda+TxM7RinV2US/FGnHJqUwukWOdZGr+3t/uU54Sfu TsQe9gCdURvJnGvMXdHO11/jBIQg4PzTKhJfnfONCo5kZMwJ1athhHVqguJyy6US SNJBlEDaO4rVMTdbYo9b =k4Mk -----END PGP SIGNATURE----- Merge tag 'mfd-next-4.16' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd Pull MFD updates from Lee Jones: "New Drivers: - Add support for RAVE Supervisory Processor Moved drivers: - Move Realtek Card Reader Driver to Misc New Device Support: - Add support for Pinctrl to axp20x New Functionality: - Add resume support to atmel-flexcom Fix-ups: - Split MFD (mfd) and userspace handlers (platform) in cros_ec - Fix trivial (whitespace, spelling) issue(s) in pcf50633-core - Clean-up error handling in ab8500-debugfs - General tidying up in tmio_core - Kconfig fix-ups for qcom-pm8xxx - Licensing changes (SPDX) to stm32-lptimer, stm32-timers - Device Tree fixups in mc13xxx - Simplify/remove unused code in cros_ec_spi, axp20x, ti_am335x_tscadc, kempld-core, intel_soc_pmic_core.c, ab8500-debugfs" * tag 'mfd-next-4.16' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (32 commits) mfd: lpc_ich: Do not touch SPI-NOR write protection bit on Apollo Lake mfd: axp20x: Mark axp288 CHRG_BAK_CTRL register volatile mfd: ab8500: Introduce DEFINE_SHOW_ATTRIBUTE() macro atmel_flexcom: Support resuming after a chip reset mfd: Remove duplicate includes dt-bindings: mfd: mc13xxx: Add the unit address to sysled mfd: stm32: Adopt SPDX identifier mfd: axp20x: Add pinctrl cell for AXP813 mfd: pm8xxx: Make elegible for COMPILE_TEST mfd: kempld-core: Use resource_size function on resource object mfd: tmio: Move register macros to tmio_core.c mfd: cros ec: spi: Simplify delay handling between SPI messages mfd: palmas: Assign the right powerhold mask for tps65917 mfd: ab8500-debugfs: Use common error handling code in ab8500_print_modem_registers() mfd: ti_am335x_tscadc: Remove redundant assignment to node mfd: pcf50633: Fix spelling mistake: 'Falied' -> 'Failed' dt-bindings: watchdog: Add bindings for RAVE SP watchdog driver watchdog: Add RAVE SP watchdog driver mfd: Add driver for RAVE Supervisory Processor serdev: Introduce devm_serdev_device_open() ...
This commit is contained in:
commit
bc4e118355
|
@ -130,7 +130,7 @@ ecspi@70010000 { /* ECSPI1 */
|
||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
led-control = <0x000 0x000 0x0e0 0x000>;
|
led-control = <0x000 0x000 0x0e0 0x000>;
|
||||||
|
|
||||||
sysled {
|
sysled@3 {
|
||||||
reg = <3>;
|
reg = <3>;
|
||||||
label = "system:red:live";
|
label = "system:red:live";
|
||||||
linux,default-trigger = "heartbeat";
|
linux,default-trigger = "heartbeat";
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
Zodiac Inflight Innovations RAVE Supervisory Processor Watchdog Bindings
|
||||||
|
|
||||||
|
RAVE SP watchdog device is a "MFD cell" device corresponding to
|
||||||
|
watchdog functionality of RAVE Supervisory Processor. It is expected
|
||||||
|
that its Device Tree node is specified as a child of the node
|
||||||
|
corresponding to the parent RAVE SP device (as documented in
|
||||||
|
Documentation/devicetree/bindings/mfd/zii,rave-sp.txt)
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
|
||||||
|
- compatible: Depending on wire protocol implemented by RAVE SP
|
||||||
|
firmware, should be one of:
|
||||||
|
- "zii,rave-sp-watchdog"
|
||||||
|
- "zii,rave-sp-watchdog-legacy"
|
||||||
|
|
||||||
|
Optional properties:
|
||||||
|
|
||||||
|
- wdt-timeout: Two byte nvmem cell specified as per
|
||||||
|
Documentation/devicetree/bindings/nvmem/nvmem.txt
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
rave-sp {
|
||||||
|
compatible = "zii,rave-sp-rdu1";
|
||||||
|
current-speed = <38400>;
|
||||||
|
|
||||||
|
eeprom {
|
||||||
|
wdt_timeout: wdt-timeout@8E {
|
||||||
|
reg = <0x8E 2>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
watchdog {
|
||||||
|
compatible = "zii,rave-sp-watchdog";
|
||||||
|
nvmem-cells = <&wdt_timeout>;
|
||||||
|
nvmem-cell-names = "wdt-timeout";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -384,6 +384,9 @@ RESET
|
||||||
devm_reset_control_get()
|
devm_reset_control_get()
|
||||||
devm_reset_controller_register()
|
devm_reset_controller_register()
|
||||||
|
|
||||||
|
SERDEV
|
||||||
|
devm_serdev_device_open()
|
||||||
|
|
||||||
SLAVE DMA ENGINE
|
SLAVE DMA ENGINE
|
||||||
devm_acpi_dma_controller_register()
|
devm_acpi_dma_controller_register()
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,6 @@
|
||||||
#include <linux/notifier.h>
|
#include <linux/notifier.h>
|
||||||
#include <linux/extcon-provider.h>
|
#include <linux/extcon-provider.h>
|
||||||
#include <linux/regmap.h>
|
#include <linux/regmap.h>
|
||||||
#include <linux/gpio.h>
|
|
||||||
#include <linux/gpio/consumer.h>
|
|
||||||
#include <linux/mfd/axp20x.h>
|
#include <linux/mfd/axp20x.h>
|
||||||
|
|
||||||
/* Power source status register */
|
/* Power source status register */
|
||||||
|
@ -79,11 +77,6 @@ enum axp288_extcon_reg {
|
||||||
AXP288_BC_DET_STAT_REG = 0x2f,
|
AXP288_BC_DET_STAT_REG = 0x2f,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum axp288_mux_select {
|
|
||||||
EXTCON_GPIO_MUX_SEL_PMIC = 0,
|
|
||||||
EXTCON_GPIO_MUX_SEL_SOC,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum axp288_extcon_irq {
|
enum axp288_extcon_irq {
|
||||||
VBUS_FALLING_IRQ = 0,
|
VBUS_FALLING_IRQ = 0,
|
||||||
VBUS_RISING_IRQ,
|
VBUS_RISING_IRQ,
|
||||||
|
@ -104,10 +97,8 @@ struct axp288_extcon_info {
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
struct regmap *regmap;
|
struct regmap *regmap;
|
||||||
struct regmap_irq_chip_data *regmap_irqc;
|
struct regmap_irq_chip_data *regmap_irqc;
|
||||||
struct gpio_desc *gpio_mux_cntl;
|
|
||||||
int irq[EXTCON_IRQ_END];
|
int irq[EXTCON_IRQ_END];
|
||||||
struct extcon_dev *edev;
|
struct extcon_dev *edev;
|
||||||
struct notifier_block extcon_nb;
|
|
||||||
unsigned int previous_cable;
|
unsigned int previous_cable;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -197,15 +188,6 @@ static int axp288_handle_chrg_det_event(struct axp288_extcon_info *info)
|
||||||
}
|
}
|
||||||
|
|
||||||
no_vbus:
|
no_vbus:
|
||||||
/*
|
|
||||||
* If VBUS is absent Connect D+/D- lines to PMIC for BC
|
|
||||||
* detection. Else connect them to SOC for USB communication.
|
|
||||||
*/
|
|
||||||
if (info->gpio_mux_cntl)
|
|
||||||
gpiod_set_value(info->gpio_mux_cntl,
|
|
||||||
vbus_attach ? EXTCON_GPIO_MUX_SEL_SOC
|
|
||||||
: EXTCON_GPIO_MUX_SEL_PMIC);
|
|
||||||
|
|
||||||
extcon_set_state_sync(info->edev, info->previous_cable, false);
|
extcon_set_state_sync(info->edev, info->previous_cable, false);
|
||||||
if (info->previous_cable == EXTCON_CHG_USB_SDP)
|
if (info->previous_cable == EXTCON_CHG_USB_SDP)
|
||||||
extcon_set_state_sync(info->edev, EXTCON_USB, false);
|
extcon_set_state_sync(info->edev, EXTCON_USB, false);
|
||||||
|
@ -253,8 +235,7 @@ static int axp288_extcon_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct axp288_extcon_info *info;
|
struct axp288_extcon_info *info;
|
||||||
struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
|
struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
|
||||||
struct axp288_extcon_pdata *pdata = pdev->dev.platform_data;
|
int ret, i, pirq;
|
||||||
int ret, i, pirq, gpio;
|
|
||||||
|
|
||||||
info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
|
info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
|
||||||
if (!info)
|
if (!info)
|
||||||
|
@ -264,8 +245,6 @@ static int axp288_extcon_probe(struct platform_device *pdev)
|
||||||
info->regmap = axp20x->regmap;
|
info->regmap = axp20x->regmap;
|
||||||
info->regmap_irqc = axp20x->regmap_irqc;
|
info->regmap_irqc = axp20x->regmap_irqc;
|
||||||
info->previous_cable = EXTCON_NONE;
|
info->previous_cable = EXTCON_NONE;
|
||||||
if (pdata)
|
|
||||||
info->gpio_mux_cntl = pdata->gpio_mux_cntl;
|
|
||||||
|
|
||||||
platform_set_drvdata(pdev, info);
|
platform_set_drvdata(pdev, info);
|
||||||
|
|
||||||
|
@ -286,21 +265,11 @@ static int axp288_extcon_probe(struct platform_device *pdev)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set up gpio control for USB Mux */
|
|
||||||
if (info->gpio_mux_cntl) {
|
|
||||||
gpio = desc_to_gpio(info->gpio_mux_cntl);
|
|
||||||
ret = devm_gpio_request(&pdev->dev, gpio, "USB_MUX");
|
|
||||||
if (ret < 0) {
|
|
||||||
dev_err(&pdev->dev,
|
|
||||||
"failed to request the gpio=%d\n", gpio);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
gpiod_direction_output(info->gpio_mux_cntl,
|
|
||||||
EXTCON_GPIO_MUX_SEL_PMIC);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < EXTCON_IRQ_END; i++) {
|
for (i = 0; i < EXTCON_IRQ_END; i++) {
|
||||||
pirq = platform_get_irq(pdev, i);
|
pirq = platform_get_irq(pdev, i);
|
||||||
|
if (pirq < 0)
|
||||||
|
return pirq;
|
||||||
|
|
||||||
info->irq[i] = regmap_irq_get_virq(info->regmap_irqc, pirq);
|
info->irq[i] = regmap_irq_get_virq(info->regmap_irqc, pirq);
|
||||||
if (info->irq[i] < 0) {
|
if (info->irq[i] < 0) {
|
||||||
dev_err(&pdev->dev,
|
dev_err(&pdev->dev,
|
||||||
|
|
|
@ -34,16 +34,26 @@ struct cros_ec_extcon_info {
|
||||||
|
|
||||||
struct notifier_block notifier;
|
struct notifier_block notifier;
|
||||||
|
|
||||||
|
unsigned int dr; /* data role */
|
||||||
|
bool pr; /* power role (true if VBUS enabled) */
|
||||||
bool dp; /* DisplayPort enabled */
|
bool dp; /* DisplayPort enabled */
|
||||||
bool mux; /* SuperSpeed (usb3) enabled */
|
bool mux; /* SuperSpeed (usb3) enabled */
|
||||||
unsigned int power_type;
|
unsigned int power_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const unsigned int usb_type_c_cable[] = {
|
static const unsigned int usb_type_c_cable[] = {
|
||||||
|
EXTCON_USB,
|
||||||
|
EXTCON_USB_HOST,
|
||||||
EXTCON_DISP_DP,
|
EXTCON_DISP_DP,
|
||||||
EXTCON_NONE,
|
EXTCON_NONE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum usb_data_roles {
|
||||||
|
DR_NONE,
|
||||||
|
DR_HOST,
|
||||||
|
DR_DEVICE,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cros_ec_pd_command() - Send a command to the EC.
|
* cros_ec_pd_command() - Send a command to the EC.
|
||||||
* @info: pointer to struct cros_ec_extcon_info
|
* @info: pointer to struct cros_ec_extcon_info
|
||||||
|
@ -150,6 +160,7 @@ static int cros_ec_usb_get_role(struct cros_ec_extcon_info *info,
|
||||||
pd_control.port = info->port_id;
|
pd_control.port = info->port_id;
|
||||||
pd_control.role = USB_PD_CTRL_ROLE_NO_CHANGE;
|
pd_control.role = USB_PD_CTRL_ROLE_NO_CHANGE;
|
||||||
pd_control.mux = USB_PD_CTRL_MUX_NO_CHANGE;
|
pd_control.mux = USB_PD_CTRL_MUX_NO_CHANGE;
|
||||||
|
pd_control.swap = USB_PD_CTRL_SWAP_NONE;
|
||||||
ret = cros_ec_pd_command(info, EC_CMD_USB_PD_CONTROL, 1,
|
ret = cros_ec_pd_command(info, EC_CMD_USB_PD_CONTROL, 1,
|
||||||
&pd_control, sizeof(pd_control),
|
&pd_control, sizeof(pd_control),
|
||||||
&resp, sizeof(resp));
|
&resp, sizeof(resp));
|
||||||
|
@ -183,11 +194,72 @@ static int cros_ec_pd_get_num_ports(struct cros_ec_extcon_info *info)
|
||||||
return resp.num_ports;
|
return resp.num_ports;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *cros_ec_usb_role_string(unsigned int role)
|
||||||
|
{
|
||||||
|
return role == DR_NONE ? "DISCONNECTED" :
|
||||||
|
(role == DR_HOST ? "DFP" : "UFP");
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *cros_ec_usb_power_type_string(unsigned int type)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case USB_CHG_TYPE_NONE:
|
||||||
|
return "USB_CHG_TYPE_NONE";
|
||||||
|
case USB_CHG_TYPE_PD:
|
||||||
|
return "USB_CHG_TYPE_PD";
|
||||||
|
case USB_CHG_TYPE_PROPRIETARY:
|
||||||
|
return "USB_CHG_TYPE_PROPRIETARY";
|
||||||
|
case USB_CHG_TYPE_C:
|
||||||
|
return "USB_CHG_TYPE_C";
|
||||||
|
case USB_CHG_TYPE_BC12_DCP:
|
||||||
|
return "USB_CHG_TYPE_BC12_DCP";
|
||||||
|
case USB_CHG_TYPE_BC12_CDP:
|
||||||
|
return "USB_CHG_TYPE_BC12_CDP";
|
||||||
|
case USB_CHG_TYPE_BC12_SDP:
|
||||||
|
return "USB_CHG_TYPE_BC12_SDP";
|
||||||
|
case USB_CHG_TYPE_OTHER:
|
||||||
|
return "USB_CHG_TYPE_OTHER";
|
||||||
|
case USB_CHG_TYPE_VBUS:
|
||||||
|
return "USB_CHG_TYPE_VBUS";
|
||||||
|
case USB_CHG_TYPE_UNKNOWN:
|
||||||
|
return "USB_CHG_TYPE_UNKNOWN";
|
||||||
|
default:
|
||||||
|
return "USB_CHG_TYPE_UNKNOWN";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool cros_ec_usb_power_type_is_wall_wart(unsigned int type,
|
||||||
|
unsigned int role)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
/* FIXME : Guppy, Donnettes, and other chargers will be miscategorized
|
||||||
|
* because they identify with USB_CHG_TYPE_C, but we can't return true
|
||||||
|
* here from that code because that breaks Suzy-Q and other kinds of
|
||||||
|
* USB Type-C cables and peripherals.
|
||||||
|
*/
|
||||||
|
case USB_CHG_TYPE_PROPRIETARY:
|
||||||
|
case USB_CHG_TYPE_BC12_DCP:
|
||||||
|
return true;
|
||||||
|
case USB_CHG_TYPE_PD:
|
||||||
|
case USB_CHG_TYPE_C:
|
||||||
|
case USB_CHG_TYPE_BC12_CDP:
|
||||||
|
case USB_CHG_TYPE_BC12_SDP:
|
||||||
|
case USB_CHG_TYPE_OTHER:
|
||||||
|
case USB_CHG_TYPE_VBUS:
|
||||||
|
case USB_CHG_TYPE_UNKNOWN:
|
||||||
|
case USB_CHG_TYPE_NONE:
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int extcon_cros_ec_detect_cable(struct cros_ec_extcon_info *info,
|
static int extcon_cros_ec_detect_cable(struct cros_ec_extcon_info *info,
|
||||||
bool force)
|
bool force)
|
||||||
{
|
{
|
||||||
struct device *dev = info->dev;
|
struct device *dev = info->dev;
|
||||||
int role, power_type;
|
int role, power_type;
|
||||||
|
unsigned int dr = DR_NONE;
|
||||||
|
bool pr = false;
|
||||||
bool polarity = false;
|
bool polarity = false;
|
||||||
bool dp = false;
|
bool dp = false;
|
||||||
bool mux = false;
|
bool mux = false;
|
||||||
|
@ -206,9 +278,12 @@ static int extcon_cros_ec_detect_cable(struct cros_ec_extcon_info *info,
|
||||||
dev_err(dev, "failed getting role err = %d\n", role);
|
dev_err(dev, "failed getting role err = %d\n", role);
|
||||||
return role;
|
return role;
|
||||||
}
|
}
|
||||||
|
dev_dbg(dev, "disconnected\n");
|
||||||
} else {
|
} else {
|
||||||
int pd_mux_state;
|
int pd_mux_state;
|
||||||
|
|
||||||
|
dr = (role & PD_CTRL_RESP_ROLE_DATA) ? DR_HOST : DR_DEVICE;
|
||||||
|
pr = (role & PD_CTRL_RESP_ROLE_POWER);
|
||||||
pd_mux_state = cros_ec_usb_get_pd_mux_state(info);
|
pd_mux_state = cros_ec_usb_get_pd_mux_state(info);
|
||||||
if (pd_mux_state < 0)
|
if (pd_mux_state < 0)
|
||||||
pd_mux_state = USB_PD_MUX_USB_ENABLED;
|
pd_mux_state = USB_PD_MUX_USB_ENABLED;
|
||||||
|
@ -216,20 +291,62 @@ static int extcon_cros_ec_detect_cable(struct cros_ec_extcon_info *info,
|
||||||
dp = pd_mux_state & USB_PD_MUX_DP_ENABLED;
|
dp = pd_mux_state & USB_PD_MUX_DP_ENABLED;
|
||||||
mux = pd_mux_state & USB_PD_MUX_USB_ENABLED;
|
mux = pd_mux_state & USB_PD_MUX_USB_ENABLED;
|
||||||
hpd = pd_mux_state & USB_PD_MUX_HPD_IRQ;
|
hpd = pd_mux_state & USB_PD_MUX_HPD_IRQ;
|
||||||
|
|
||||||
|
dev_dbg(dev,
|
||||||
|
"connected role 0x%x pwr type %d dr %d pr %d pol %d mux %d dp %d hpd %d\n",
|
||||||
|
role, power_type, dr, pr, polarity, mux, dp, hpd);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (force || info->dp != dp || info->mux != mux ||
|
/*
|
||||||
info->power_type != power_type) {
|
* When there is no USB host (e.g. USB PD charger),
|
||||||
|
* we are not really a UFP for the AP.
|
||||||
|
*/
|
||||||
|
if (dr == DR_DEVICE &&
|
||||||
|
cros_ec_usb_power_type_is_wall_wart(power_type, role))
|
||||||
|
dr = DR_NONE;
|
||||||
|
|
||||||
|
if (force || info->dr != dr || info->pr != pr || info->dp != dp ||
|
||||||
|
info->mux != mux || info->power_type != power_type) {
|
||||||
|
bool host_connected = false, device_connected = false;
|
||||||
|
|
||||||
|
dev_dbg(dev, "Type/Role switch! type = %s role = %s\n",
|
||||||
|
cros_ec_usb_power_type_string(power_type),
|
||||||
|
cros_ec_usb_role_string(dr));
|
||||||
|
info->dr = dr;
|
||||||
|
info->pr = pr;
|
||||||
info->dp = dp;
|
info->dp = dp;
|
||||||
info->mux = mux;
|
info->mux = mux;
|
||||||
info->power_type = power_type;
|
info->power_type = power_type;
|
||||||
|
|
||||||
extcon_set_state(info->edev, EXTCON_DISP_DP, dp);
|
if (dr == DR_DEVICE)
|
||||||
|
device_connected = true;
|
||||||
|
else if (dr == DR_HOST)
|
||||||
|
host_connected = true;
|
||||||
|
|
||||||
|
extcon_set_state(info->edev, EXTCON_USB, device_connected);
|
||||||
|
extcon_set_state(info->edev, EXTCON_USB_HOST, host_connected);
|
||||||
|
extcon_set_state(info->edev, EXTCON_DISP_DP, dp);
|
||||||
|
extcon_set_property(info->edev, EXTCON_USB,
|
||||||
|
EXTCON_PROP_USB_VBUS,
|
||||||
|
(union extcon_property_value)(int)pr);
|
||||||
|
extcon_set_property(info->edev, EXTCON_USB_HOST,
|
||||||
|
EXTCON_PROP_USB_VBUS,
|
||||||
|
(union extcon_property_value)(int)pr);
|
||||||
|
extcon_set_property(info->edev, EXTCON_USB,
|
||||||
|
EXTCON_PROP_USB_TYPEC_POLARITY,
|
||||||
|
(union extcon_property_value)(int)polarity);
|
||||||
|
extcon_set_property(info->edev, EXTCON_USB_HOST,
|
||||||
|
EXTCON_PROP_USB_TYPEC_POLARITY,
|
||||||
|
(union extcon_property_value)(int)polarity);
|
||||||
extcon_set_property(info->edev, EXTCON_DISP_DP,
|
extcon_set_property(info->edev, EXTCON_DISP_DP,
|
||||||
EXTCON_PROP_USB_TYPEC_POLARITY,
|
EXTCON_PROP_USB_TYPEC_POLARITY,
|
||||||
(union extcon_property_value)(int)polarity);
|
(union extcon_property_value)(int)polarity);
|
||||||
|
extcon_set_property(info->edev, EXTCON_USB,
|
||||||
|
EXTCON_PROP_USB_SS,
|
||||||
|
(union extcon_property_value)(int)mux);
|
||||||
|
extcon_set_property(info->edev, EXTCON_USB_HOST,
|
||||||
|
EXTCON_PROP_USB_SS,
|
||||||
|
(union extcon_property_value)(int)mux);
|
||||||
extcon_set_property(info->edev, EXTCON_DISP_DP,
|
extcon_set_property(info->edev, EXTCON_DISP_DP,
|
||||||
EXTCON_PROP_USB_SS,
|
EXTCON_PROP_USB_SS,
|
||||||
(union extcon_property_value)(int)mux);
|
(union extcon_property_value)(int)mux);
|
||||||
|
@ -237,6 +354,8 @@ static int extcon_cros_ec_detect_cable(struct cros_ec_extcon_info *info,
|
||||||
EXTCON_PROP_DISP_HPD,
|
EXTCON_PROP_DISP_HPD,
|
||||||
(union extcon_property_value)(int)hpd);
|
(union extcon_property_value)(int)hpd);
|
||||||
|
|
||||||
|
extcon_sync(info->edev, EXTCON_USB);
|
||||||
|
extcon_sync(info->edev, EXTCON_USB_HOST);
|
||||||
extcon_sync(info->edev, EXTCON_DISP_DP);
|
extcon_sync(info->edev, EXTCON_DISP_DP);
|
||||||
|
|
||||||
} else if (hpd) {
|
} else if (hpd) {
|
||||||
|
@ -322,13 +441,28 @@ static int extcon_cros_ec_probe(struct platform_device *pdev)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extcon_set_property_capability(info->edev, EXTCON_USB,
|
||||||
|
EXTCON_PROP_USB_VBUS);
|
||||||
|
extcon_set_property_capability(info->edev, EXTCON_USB_HOST,
|
||||||
|
EXTCON_PROP_USB_VBUS);
|
||||||
|
extcon_set_property_capability(info->edev, EXTCON_USB,
|
||||||
|
EXTCON_PROP_USB_TYPEC_POLARITY);
|
||||||
|
extcon_set_property_capability(info->edev, EXTCON_USB_HOST,
|
||||||
|
EXTCON_PROP_USB_TYPEC_POLARITY);
|
||||||
extcon_set_property_capability(info->edev, EXTCON_DISP_DP,
|
extcon_set_property_capability(info->edev, EXTCON_DISP_DP,
|
||||||
EXTCON_PROP_USB_TYPEC_POLARITY);
|
EXTCON_PROP_USB_TYPEC_POLARITY);
|
||||||
|
extcon_set_property_capability(info->edev, EXTCON_USB,
|
||||||
|
EXTCON_PROP_USB_SS);
|
||||||
|
extcon_set_property_capability(info->edev, EXTCON_USB_HOST,
|
||||||
|
EXTCON_PROP_USB_SS);
|
||||||
extcon_set_property_capability(info->edev, EXTCON_DISP_DP,
|
extcon_set_property_capability(info->edev, EXTCON_DISP_DP,
|
||||||
EXTCON_PROP_USB_SS);
|
EXTCON_PROP_USB_SS);
|
||||||
extcon_set_property_capability(info->edev, EXTCON_DISP_DP,
|
extcon_set_property_capability(info->edev, EXTCON_DISP_DP,
|
||||||
EXTCON_PROP_DISP_HPD);
|
EXTCON_PROP_DISP_HPD);
|
||||||
|
|
||||||
|
info->dr = DR_NONE;
|
||||||
|
info->pr = false;
|
||||||
|
|
||||||
platform_set_drvdata(pdev, info);
|
platform_set_drvdata(pdev, info);
|
||||||
|
|
||||||
/* Get PD events from the EC */
|
/* Get PD events from the EC */
|
||||||
|
|
|
@ -106,7 +106,7 @@ static int pm8058_led_probe(struct platform_device *pdev)
|
||||||
if (!led)
|
if (!led)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
led->ledtype = (u32)of_device_get_match_data(&pdev->dev);
|
led->ledtype = (u32)(unsigned long)of_device_get_match_data(&pdev->dev);
|
||||||
|
|
||||||
map = dev_get_regmap(pdev->dev.parent, NULL);
|
map = dev_get_regmap(pdev->dev.parent, NULL);
|
||||||
if (!map) {
|
if (!map) {
|
||||||
|
|
|
@ -45,7 +45,7 @@ config MEMSTICK_R592
|
||||||
|
|
||||||
config MEMSTICK_REALTEK_PCI
|
config MEMSTICK_REALTEK_PCI
|
||||||
tristate "Realtek PCI-E Memstick Card Interface Driver"
|
tristate "Realtek PCI-E Memstick Card Interface Driver"
|
||||||
depends on MFD_RTSX_PCI
|
depends on MISC_RTSX_PCI
|
||||||
help
|
help
|
||||||
Say Y here to include driver code to support Memstick card interface
|
Say Y here to include driver code to support Memstick card interface
|
||||||
of Realtek PCI-E card reader
|
of Realtek PCI-E card reader
|
||||||
|
@ -55,7 +55,7 @@ config MEMSTICK_REALTEK_PCI
|
||||||
|
|
||||||
config MEMSTICK_REALTEK_USB
|
config MEMSTICK_REALTEK_USB
|
||||||
tristate "Realtek USB Memstick Card Interface Driver"
|
tristate "Realtek USB Memstick Card Interface Driver"
|
||||||
depends on MFD_RTSX_USB
|
depends on MISC_RTSX_USB
|
||||||
help
|
help
|
||||||
Say Y here to include driver code to support Memstick card interface
|
Say Y here to include driver code to support Memstick card interface
|
||||||
of Realtek RTS5129/39 series USB card reader
|
of Realtek RTS5129/39 series USB card reader
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/memstick.h>
|
#include <linux/memstick.h>
|
||||||
#include <linux/mfd/rtsx_pci.h>
|
#include <linux/rtsx_pci.h>
|
||||||
#include <asm/unaligned.h>
|
#include <asm/unaligned.h>
|
||||||
|
|
||||||
struct realtek_pci_ms {
|
struct realtek_pci_ms {
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
#include <linux/memstick.h>
|
#include <linux/memstick.h>
|
||||||
#include <linux/kthread.h>
|
#include <linux/kthread.h>
|
||||||
#include <linux/mfd/rtsx_usb.h>
|
#include <linux/rtsx_usb.h>
|
||||||
#include <linux/pm_runtime.h>
|
#include <linux/pm_runtime.h>
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
|
|
|
@ -222,6 +222,16 @@ config MFD_CROS_EC_SPI
|
||||||
response time cannot be guaranteed, we support ignoring
|
response time cannot be guaranteed, we support ignoring
|
||||||
'pre-amble' bytes before the response actually starts.
|
'pre-amble' bytes before the response actually starts.
|
||||||
|
|
||||||
|
config MFD_CROS_EC_CHARDEV
|
||||||
|
tristate "Chrome OS Embedded Controller userspace device interface"
|
||||||
|
depends on MFD_CROS_EC
|
||||||
|
select CROS_EC_CTL
|
||||||
|
---help---
|
||||||
|
This driver adds support to talk with the ChromeOS EC from userspace.
|
||||||
|
|
||||||
|
If you have a supported Chromebook, choose Y or M here.
|
||||||
|
The module will be called cros_ec_dev.
|
||||||
|
|
||||||
config MFD_ASIC3
|
config MFD_ASIC3
|
||||||
bool "Compaq ASIC3"
|
bool "Compaq ASIC3"
|
||||||
depends on GPIOLIB && ARM
|
depends on GPIOLIB && ARM
|
||||||
|
@ -877,7 +887,7 @@ config UCB1400_CORE
|
||||||
|
|
||||||
config MFD_PM8XXX
|
config MFD_PM8XXX
|
||||||
tristate "Qualcomm PM8xxx PMIC chips driver"
|
tristate "Qualcomm PM8xxx PMIC chips driver"
|
||||||
depends on (ARM || HEXAGON)
|
depends on (ARM || HEXAGON || COMPILE_TEST)
|
||||||
select IRQ_DOMAIN
|
select IRQ_DOMAIN
|
||||||
select MFD_CORE
|
select MFD_CORE
|
||||||
select REGMAP
|
select REGMAP
|
||||||
|
@ -929,17 +939,6 @@ config MFD_RDC321X
|
||||||
southbridge which provides access to GPIOs and Watchdog using the
|
southbridge which provides access to GPIOs and Watchdog using the
|
||||||
southbridge PCI device configuration space.
|
southbridge PCI device configuration space.
|
||||||
|
|
||||||
config MFD_RTSX_PCI
|
|
||||||
tristate "Realtek PCI-E card reader"
|
|
||||||
depends on PCI
|
|
||||||
select MFD_CORE
|
|
||||||
help
|
|
||||||
This supports for Realtek PCI-Express card reader including rts5209,
|
|
||||||
rts5227, rts522A, rts5229, rts5249, rts524A, rts525A, rtl8411, etc.
|
|
||||||
Realtek card reader supports access to many types of memory cards,
|
|
||||||
such as Memory Stick, Memory Stick Pro, Secure Digital and
|
|
||||||
MultiMediaCard.
|
|
||||||
|
|
||||||
config MFD_RT5033
|
config MFD_RT5033
|
||||||
tristate "Richtek RT5033 Power Management IC"
|
tristate "Richtek RT5033 Power Management IC"
|
||||||
depends on I2C
|
depends on I2C
|
||||||
|
@ -953,16 +952,6 @@ config MFD_RT5033
|
||||||
sub-devices like charger, fuel gauge, flash LED, current source,
|
sub-devices like charger, fuel gauge, flash LED, current source,
|
||||||
LDO and Buck.
|
LDO and Buck.
|
||||||
|
|
||||||
config MFD_RTSX_USB
|
|
||||||
tristate "Realtek USB card reader"
|
|
||||||
depends on USB
|
|
||||||
select MFD_CORE
|
|
||||||
help
|
|
||||||
Select this option to get support for Realtek USB 2.0 card readers
|
|
||||||
including RTS5129, RTS5139, RTS5179 and RTS5170.
|
|
||||||
Realtek card reader supports access to many types of memory cards,
|
|
||||||
such as Memory Stick Pro, Secure Digital and MultiMediaCard.
|
|
||||||
|
|
||||||
config MFD_RC5T583
|
config MFD_RC5T583
|
||||||
bool "Ricoh RC5T583 Power Management system device"
|
bool "Ricoh RC5T583 Power Management system device"
|
||||||
depends on I2C=y
|
depends on I2C=y
|
||||||
|
@ -1859,5 +1848,13 @@ config MFD_VEXPRESS_SYSREG
|
||||||
System Registers are the platform configuration block
|
System Registers are the platform configuration block
|
||||||
on the ARM Ltd. Versatile Express board.
|
on the ARM Ltd. Versatile Express board.
|
||||||
|
|
||||||
|
config RAVE_SP_CORE
|
||||||
|
tristate "RAVE SP MCU core driver"
|
||||||
|
depends on SERIAL_DEV_BUS
|
||||||
|
select CRC_CCITT
|
||||||
|
help
|
||||||
|
Select this to get support for the Supervisory Processor
|
||||||
|
device found on several devices in RAVE line of hardware.
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -17,12 +17,9 @@ cros_ec_core-$(CONFIG_ACPI) += cros_ec_acpi_gpe.o
|
||||||
obj-$(CONFIG_MFD_CROS_EC) += cros_ec_core.o
|
obj-$(CONFIG_MFD_CROS_EC) += cros_ec_core.o
|
||||||
obj-$(CONFIG_MFD_CROS_EC_I2C) += cros_ec_i2c.o
|
obj-$(CONFIG_MFD_CROS_EC_I2C) += cros_ec_i2c.o
|
||||||
obj-$(CONFIG_MFD_CROS_EC_SPI) += cros_ec_spi.o
|
obj-$(CONFIG_MFD_CROS_EC_SPI) += cros_ec_spi.o
|
||||||
|
obj-$(CONFIG_MFD_CROS_EC_CHARDEV) += cros_ec_dev.o
|
||||||
obj-$(CONFIG_MFD_EXYNOS_LPASS) += exynos-lpass.o
|
obj-$(CONFIG_MFD_EXYNOS_LPASS) += exynos-lpass.o
|
||||||
|
|
||||||
rtsx_pci-objs := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o rts5227.o rts5249.o
|
|
||||||
obj-$(CONFIG_MFD_RTSX_PCI) += rtsx_pci.o
|
|
||||||
obj-$(CONFIG_MFD_RTSX_USB) += rtsx_usb.o
|
|
||||||
|
|
||||||
obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o
|
obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o
|
||||||
obj-$(CONFIG_HTC_I2CPLD) += htc-i2cpld.o
|
obj-$(CONFIG_HTC_I2CPLD) += htc-i2cpld.o
|
||||||
|
|
||||||
|
@ -230,3 +227,5 @@ obj-$(CONFIG_MFD_STM32_LPTIMER) += stm32-lptimer.o
|
||||||
obj-$(CONFIG_MFD_STM32_TIMERS) += stm32-timers.o
|
obj-$(CONFIG_MFD_STM32_TIMERS) += stm32-timers.o
|
||||||
obj-$(CONFIG_MFD_MXS_LRADC) += mxs-lradc.o
|
obj-$(CONFIG_MFD_MXS_LRADC) += mxs-lradc.o
|
||||||
obj-$(CONFIG_MFD_SC27XX_PMIC) += sprd-sc27xx-spi.o
|
obj-$(CONFIG_MFD_SC27XX_PMIC) += sprd-sc27xx-spi.o
|
||||||
|
obj-$(CONFIG_RAVE_SP_CORE) += rave-sp.o
|
||||||
|
|
||||||
|
|
|
@ -1258,6 +1258,19 @@ static struct ab8500_prcmu_ranges ab8540_debug_ranges[AB8500_NUM_BANKS] = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define DEFINE_SHOW_ATTRIBUTE(__name) \
|
||||||
|
static int __name ## _open(struct inode *inode, struct file *file) \
|
||||||
|
{ \
|
||||||
|
return single_open(file, __name ## _show, inode->i_private); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
static const struct file_operations __name ## _fops = { \
|
||||||
|
.owner = THIS_MODULE, \
|
||||||
|
.open = __name ## _open, \
|
||||||
|
.read = seq_read, \
|
||||||
|
.llseek = seq_lseek, \
|
||||||
|
.release = single_release, \
|
||||||
|
} \
|
||||||
|
|
||||||
static irqreturn_t ab8500_debug_handler(int irq, void *data)
|
static irqreturn_t ab8500_debug_handler(int irq, void *data)
|
||||||
{
|
{
|
||||||
|
@ -1318,7 +1331,7 @@ static int ab8500_registers_print(struct device *dev, u32 bank,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ab8500_print_bank_registers(struct seq_file *s, void *p)
|
static int ab8500_bank_registers_show(struct seq_file *s, void *p)
|
||||||
{
|
{
|
||||||
struct device *dev = s->private;
|
struct device *dev = s->private;
|
||||||
u32 bank = debug_bank;
|
u32 bank = debug_bank;
|
||||||
|
@ -1330,18 +1343,7 @@ static int ab8500_print_bank_registers(struct seq_file *s, void *p)
|
||||||
return ab8500_registers_print(dev, bank, s);
|
return ab8500_registers_print(dev, bank, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ab8500_registers_open(struct inode *inode, struct file *file)
|
DEFINE_SHOW_ATTRIBUTE(ab8500_bank_registers);
|
||||||
{
|
|
||||||
return single_open(file, ab8500_print_bank_registers, inode->i_private);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct file_operations ab8500_registers_fops = {
|
|
||||||
.open = ab8500_registers_open,
|
|
||||||
.read = seq_read,
|
|
||||||
.llseek = seq_lseek,
|
|
||||||
.release = single_release,
|
|
||||||
.owner = THIS_MODULE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int ab8500_print_all_banks(struct seq_file *s, void *p)
|
static int ab8500_print_all_banks(struct seq_file *s, void *p)
|
||||||
{
|
{
|
||||||
|
@ -1528,7 +1530,7 @@ void ab8500_debug_register_interrupt(int line)
|
||||||
num_interrupts[line]++;
|
num_interrupts[line]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ab8500_interrupts_print(struct seq_file *s, void *p)
|
static int ab8500_interrupts_show(struct seq_file *s, void *p)
|
||||||
{
|
{
|
||||||
int line;
|
int line;
|
||||||
|
|
||||||
|
@ -1557,10 +1559,7 @@ static int ab8500_interrupts_print(struct seq_file *s, void *p)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ab8500_interrupts_open(struct inode *inode, struct file *file)
|
DEFINE_SHOW_ATTRIBUTE(ab8500_interrupts);
|
||||||
{
|
|
||||||
return single_open(file, ab8500_interrupts_print, inode->i_private);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* - HWREG DB8500 formated routines
|
* - HWREG DB8500 formated routines
|
||||||
|
@ -1603,7 +1602,7 @@ static int ab8500_hwreg_open(struct inode *inode, struct file *file)
|
||||||
#define AB8500_LAST_SIM_REG 0x8B
|
#define AB8500_LAST_SIM_REG 0x8B
|
||||||
#define AB8505_LAST_SIM_REG 0x8C
|
#define AB8505_LAST_SIM_REG 0x8C
|
||||||
|
|
||||||
static int ab8500_print_modem_registers(struct seq_file *s, void *p)
|
static int ab8500_modem_show(struct seq_file *s, void *p)
|
||||||
{
|
{
|
||||||
struct device *dev = s->private;
|
struct device *dev = s->private;
|
||||||
struct ab8500 *ab8500;
|
struct ab8500 *ab8500;
|
||||||
|
@ -1620,18 +1619,15 @@ static int ab8500_print_modem_registers(struct seq_file *s, void *p)
|
||||||
|
|
||||||
err = abx500_get_register_interruptible(dev,
|
err = abx500_get_register_interruptible(dev,
|
||||||
AB8500_REGU_CTRL1, AB8500_SUPPLY_CONTROL_REG, &orig_value);
|
AB8500_REGU_CTRL1, AB8500_SUPPLY_CONTROL_REG, &orig_value);
|
||||||
if (err < 0) {
|
if (err < 0)
|
||||||
dev_err(dev, "ab->read fail %d\n", err);
|
goto report_read_failure;
|
||||||
return err;
|
|
||||||
}
|
|
||||||
/* Config 1 will allow APE side to read SIM registers */
|
/* Config 1 will allow APE side to read SIM registers */
|
||||||
err = abx500_set_register_interruptible(dev,
|
err = abx500_set_register_interruptible(dev,
|
||||||
AB8500_REGU_CTRL1, AB8500_SUPPLY_CONTROL_REG,
|
AB8500_REGU_CTRL1, AB8500_SUPPLY_CONTROL_REG,
|
||||||
AB8500_SUPPLY_CONTROL_CONFIG_1);
|
AB8500_SUPPLY_CONTROL_CONFIG_1);
|
||||||
if (err < 0) {
|
if (err < 0)
|
||||||
dev_err(dev, "ab->write fail %d\n", err);
|
goto report_write_failure;
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
seq_printf(s, " bank 0x%02X:\n", bank);
|
seq_printf(s, " bank 0x%02X:\n", bank);
|
||||||
|
|
||||||
|
@ -1641,36 +1637,30 @@ static int ab8500_print_modem_registers(struct seq_file *s, void *p)
|
||||||
for (reg = AB8500_FIRST_SIM_REG; reg <= last_sim_reg; reg++) {
|
for (reg = AB8500_FIRST_SIM_REG; reg <= last_sim_reg; reg++) {
|
||||||
err = abx500_get_register_interruptible(dev,
|
err = abx500_get_register_interruptible(dev,
|
||||||
bank, reg, &value);
|
bank, reg, &value);
|
||||||
if (err < 0) {
|
if (err < 0)
|
||||||
dev_err(dev, "ab->read fail %d\n", err);
|
goto report_read_failure;
|
||||||
return err;
|
|
||||||
}
|
|
||||||
seq_printf(s, " [0x%02X/0x%02X]: 0x%02X\n", bank, reg, value);
|
seq_printf(s, " [0x%02X/0x%02X]: 0x%02X\n", bank, reg, value);
|
||||||
}
|
}
|
||||||
err = abx500_set_register_interruptible(dev,
|
err = abx500_set_register_interruptible(dev,
|
||||||
AB8500_REGU_CTRL1, AB8500_SUPPLY_CONTROL_REG, orig_value);
|
AB8500_REGU_CTRL1, AB8500_SUPPLY_CONTROL_REG, orig_value);
|
||||||
if (err < 0) {
|
if (err < 0)
|
||||||
dev_err(dev, "ab->write fail %d\n", err);
|
goto report_write_failure;
|
||||||
return err;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
report_read_failure:
|
||||||
|
dev_err(dev, "ab->read fail %d\n", err);
|
||||||
|
return err;
|
||||||
|
|
||||||
|
report_write_failure:
|
||||||
|
dev_err(dev, "ab->write fail %d\n", err);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ab8500_modem_open(struct inode *inode, struct file *file)
|
DEFINE_SHOW_ATTRIBUTE(ab8500_modem);
|
||||||
{
|
|
||||||
return single_open(file, ab8500_print_modem_registers,
|
|
||||||
inode->i_private);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct file_operations ab8500_modem_fops = {
|
static int ab8500_gpadc_bat_ctrl_show(struct seq_file *s, void *p)
|
||||||
.open = ab8500_modem_open,
|
|
||||||
.read = seq_read,
|
|
||||||
.llseek = seq_lseek,
|
|
||||||
.release = single_release,
|
|
||||||
.owner = THIS_MODULE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int ab8500_gpadc_bat_ctrl_print(struct seq_file *s, void *p)
|
|
||||||
{
|
{
|
||||||
int bat_ctrl_raw;
|
int bat_ctrl_raw;
|
||||||
int bat_ctrl_convert;
|
int bat_ctrl_convert;
|
||||||
|
@ -1687,21 +1677,9 @@ static int ab8500_gpadc_bat_ctrl_print(struct seq_file *s, void *p)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ab8500_gpadc_bat_ctrl_open(struct inode *inode, struct file *file)
|
DEFINE_SHOW_ATTRIBUTE(ab8500_gpadc_bat_ctrl);
|
||||||
{
|
|
||||||
return single_open(file, ab8500_gpadc_bat_ctrl_print,
|
|
||||||
inode->i_private);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct file_operations ab8500_gpadc_bat_ctrl_fops = {
|
static int ab8500_gpadc_btemp_ball_show(struct seq_file *s, void *p)
|
||||||
.open = ab8500_gpadc_bat_ctrl_open,
|
|
||||||
.read = seq_read,
|
|
||||||
.llseek = seq_lseek,
|
|
||||||
.release = single_release,
|
|
||||||
.owner = THIS_MODULE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int ab8500_gpadc_btemp_ball_print(struct seq_file *s, void *p)
|
|
||||||
{
|
{
|
||||||
int btemp_ball_raw;
|
int btemp_ball_raw;
|
||||||
int btemp_ball_convert;
|
int btemp_ball_convert;
|
||||||
|
@ -1718,22 +1696,9 @@ static int ab8500_gpadc_btemp_ball_print(struct seq_file *s, void *p)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ab8500_gpadc_btemp_ball_open(struct inode *inode,
|
DEFINE_SHOW_ATTRIBUTE(ab8500_gpadc_btemp_ball);
|
||||||
struct file *file)
|
|
||||||
{
|
|
||||||
return single_open(file, ab8500_gpadc_btemp_ball_print,
|
|
||||||
inode->i_private);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct file_operations ab8500_gpadc_btemp_ball_fops = {
|
static int ab8500_gpadc_main_charger_v_show(struct seq_file *s, void *p)
|
||||||
.open = ab8500_gpadc_btemp_ball_open,
|
|
||||||
.read = seq_read,
|
|
||||||
.llseek = seq_lseek,
|
|
||||||
.release = single_release,
|
|
||||||
.owner = THIS_MODULE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int ab8500_gpadc_main_charger_v_print(struct seq_file *s, void *p)
|
|
||||||
{
|
{
|
||||||
int main_charger_v_raw;
|
int main_charger_v_raw;
|
||||||
int main_charger_v_convert;
|
int main_charger_v_convert;
|
||||||
|
@ -1750,22 +1715,9 @@ static int ab8500_gpadc_main_charger_v_print(struct seq_file *s, void *p)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ab8500_gpadc_main_charger_v_open(struct inode *inode,
|
DEFINE_SHOW_ATTRIBUTE(ab8500_gpadc_main_charger_v);
|
||||||
struct file *file)
|
|
||||||
{
|
|
||||||
return single_open(file, ab8500_gpadc_main_charger_v_print,
|
|
||||||
inode->i_private);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct file_operations ab8500_gpadc_main_charger_v_fops = {
|
static int ab8500_gpadc_acc_detect1_show(struct seq_file *s, void *p)
|
||||||
.open = ab8500_gpadc_main_charger_v_open,
|
|
||||||
.read = seq_read,
|
|
||||||
.llseek = seq_lseek,
|
|
||||||
.release = single_release,
|
|
||||||
.owner = THIS_MODULE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int ab8500_gpadc_acc_detect1_print(struct seq_file *s, void *p)
|
|
||||||
{
|
{
|
||||||
int acc_detect1_raw;
|
int acc_detect1_raw;
|
||||||
int acc_detect1_convert;
|
int acc_detect1_convert;
|
||||||
|
@ -1782,22 +1734,9 @@ static int ab8500_gpadc_acc_detect1_print(struct seq_file *s, void *p)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ab8500_gpadc_acc_detect1_open(struct inode *inode,
|
DEFINE_SHOW_ATTRIBUTE(ab8500_gpadc_acc_detect1);
|
||||||
struct file *file)
|
|
||||||
{
|
|
||||||
return single_open(file, ab8500_gpadc_acc_detect1_print,
|
|
||||||
inode->i_private);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct file_operations ab8500_gpadc_acc_detect1_fops = {
|
static int ab8500_gpadc_acc_detect2_show(struct seq_file *s, void *p)
|
||||||
.open = ab8500_gpadc_acc_detect1_open,
|
|
||||||
.read = seq_read,
|
|
||||||
.llseek = seq_lseek,
|
|
||||||
.release = single_release,
|
|
||||||
.owner = THIS_MODULE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int ab8500_gpadc_acc_detect2_print(struct seq_file *s, void *p)
|
|
||||||
{
|
{
|
||||||
int acc_detect2_raw;
|
int acc_detect2_raw;
|
||||||
int acc_detect2_convert;
|
int acc_detect2_convert;
|
||||||
|
@ -1814,22 +1753,9 @@ static int ab8500_gpadc_acc_detect2_print(struct seq_file *s, void *p)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ab8500_gpadc_acc_detect2_open(struct inode *inode,
|
DEFINE_SHOW_ATTRIBUTE(ab8500_gpadc_acc_detect2);
|
||||||
struct file *file)
|
|
||||||
{
|
|
||||||
return single_open(file, ab8500_gpadc_acc_detect2_print,
|
|
||||||
inode->i_private);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct file_operations ab8500_gpadc_acc_detect2_fops = {
|
static int ab8500_gpadc_aux1_show(struct seq_file *s, void *p)
|
||||||
.open = ab8500_gpadc_acc_detect2_open,
|
|
||||||
.read = seq_read,
|
|
||||||
.llseek = seq_lseek,
|
|
||||||
.release = single_release,
|
|
||||||
.owner = THIS_MODULE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int ab8500_gpadc_aux1_print(struct seq_file *s, void *p)
|
|
||||||
{
|
{
|
||||||
int aux1_raw;
|
int aux1_raw;
|
||||||
int aux1_convert;
|
int aux1_convert;
|
||||||
|
@ -1846,20 +1772,9 @@ static int ab8500_gpadc_aux1_print(struct seq_file *s, void *p)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ab8500_gpadc_aux1_open(struct inode *inode, struct file *file)
|
DEFINE_SHOW_ATTRIBUTE(ab8500_gpadc_aux1);
|
||||||
{
|
|
||||||
return single_open(file, ab8500_gpadc_aux1_print, inode->i_private);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct file_operations ab8500_gpadc_aux1_fops = {
|
static int ab8500_gpadc_aux2_show(struct seq_file *s, void *p)
|
||||||
.open = ab8500_gpadc_aux1_open,
|
|
||||||
.read = seq_read,
|
|
||||||
.llseek = seq_lseek,
|
|
||||||
.release = single_release,
|
|
||||||
.owner = THIS_MODULE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int ab8500_gpadc_aux2_print(struct seq_file *s, void *p)
|
|
||||||
{
|
{
|
||||||
int aux2_raw;
|
int aux2_raw;
|
||||||
int aux2_convert;
|
int aux2_convert;
|
||||||
|
@ -1876,20 +1791,9 @@ static int ab8500_gpadc_aux2_print(struct seq_file *s, void *p)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ab8500_gpadc_aux2_open(struct inode *inode, struct file *file)
|
DEFINE_SHOW_ATTRIBUTE(ab8500_gpadc_aux2);
|
||||||
{
|
|
||||||
return single_open(file, ab8500_gpadc_aux2_print, inode->i_private);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct file_operations ab8500_gpadc_aux2_fops = {
|
static int ab8500_gpadc_main_bat_v_show(struct seq_file *s, void *p)
|
||||||
.open = ab8500_gpadc_aux2_open,
|
|
||||||
.read = seq_read,
|
|
||||||
.llseek = seq_lseek,
|
|
||||||
.release = single_release,
|
|
||||||
.owner = THIS_MODULE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int ab8500_gpadc_main_bat_v_print(struct seq_file *s, void *p)
|
|
||||||
{
|
{
|
||||||
int main_bat_v_raw;
|
int main_bat_v_raw;
|
||||||
int main_bat_v_convert;
|
int main_bat_v_convert;
|
||||||
|
@ -1906,22 +1810,9 @@ static int ab8500_gpadc_main_bat_v_print(struct seq_file *s, void *p)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ab8500_gpadc_main_bat_v_open(struct inode *inode,
|
DEFINE_SHOW_ATTRIBUTE(ab8500_gpadc_main_bat_v);
|
||||||
struct file *file)
|
|
||||||
{
|
|
||||||
return single_open(file, ab8500_gpadc_main_bat_v_print,
|
|
||||||
inode->i_private);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct file_operations ab8500_gpadc_main_bat_v_fops = {
|
static int ab8500_gpadc_vbus_v_show(struct seq_file *s, void *p)
|
||||||
.open = ab8500_gpadc_main_bat_v_open,
|
|
||||||
.read = seq_read,
|
|
||||||
.llseek = seq_lseek,
|
|
||||||
.release = single_release,
|
|
||||||
.owner = THIS_MODULE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int ab8500_gpadc_vbus_v_print(struct seq_file *s, void *p)
|
|
||||||
{
|
{
|
||||||
int vbus_v_raw;
|
int vbus_v_raw;
|
||||||
int vbus_v_convert;
|
int vbus_v_convert;
|
||||||
|
@ -1938,20 +1829,9 @@ static int ab8500_gpadc_vbus_v_print(struct seq_file *s, void *p)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ab8500_gpadc_vbus_v_open(struct inode *inode, struct file *file)
|
DEFINE_SHOW_ATTRIBUTE(ab8500_gpadc_vbus_v);
|
||||||
{
|
|
||||||
return single_open(file, ab8500_gpadc_vbus_v_print, inode->i_private);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct file_operations ab8500_gpadc_vbus_v_fops = {
|
static int ab8500_gpadc_main_charger_c_show(struct seq_file *s, void *p)
|
||||||
.open = ab8500_gpadc_vbus_v_open,
|
|
||||||
.read = seq_read,
|
|
||||||
.llseek = seq_lseek,
|
|
||||||
.release = single_release,
|
|
||||||
.owner = THIS_MODULE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int ab8500_gpadc_main_charger_c_print(struct seq_file *s, void *p)
|
|
||||||
{
|
{
|
||||||
int main_charger_c_raw;
|
int main_charger_c_raw;
|
||||||
int main_charger_c_convert;
|
int main_charger_c_convert;
|
||||||
|
@ -1968,22 +1848,9 @@ static int ab8500_gpadc_main_charger_c_print(struct seq_file *s, void *p)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ab8500_gpadc_main_charger_c_open(struct inode *inode,
|
DEFINE_SHOW_ATTRIBUTE(ab8500_gpadc_main_charger_c);
|
||||||
struct file *file)
|
|
||||||
{
|
|
||||||
return single_open(file, ab8500_gpadc_main_charger_c_print,
|
|
||||||
inode->i_private);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct file_operations ab8500_gpadc_main_charger_c_fops = {
|
static int ab8500_gpadc_usb_charger_c_show(struct seq_file *s, void *p)
|
||||||
.open = ab8500_gpadc_main_charger_c_open,
|
|
||||||
.read = seq_read,
|
|
||||||
.llseek = seq_lseek,
|
|
||||||
.release = single_release,
|
|
||||||
.owner = THIS_MODULE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int ab8500_gpadc_usb_charger_c_print(struct seq_file *s, void *p)
|
|
||||||
{
|
{
|
||||||
int usb_charger_c_raw;
|
int usb_charger_c_raw;
|
||||||
int usb_charger_c_convert;
|
int usb_charger_c_convert;
|
||||||
|
@ -2000,22 +1867,9 @@ static int ab8500_gpadc_usb_charger_c_print(struct seq_file *s, void *p)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ab8500_gpadc_usb_charger_c_open(struct inode *inode,
|
DEFINE_SHOW_ATTRIBUTE(ab8500_gpadc_usb_charger_c);
|
||||||
struct file *file)
|
|
||||||
{
|
|
||||||
return single_open(file, ab8500_gpadc_usb_charger_c_print,
|
|
||||||
inode->i_private);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct file_operations ab8500_gpadc_usb_charger_c_fops = {
|
static int ab8500_gpadc_bk_bat_v_show(struct seq_file *s, void *p)
|
||||||
.open = ab8500_gpadc_usb_charger_c_open,
|
|
||||||
.read = seq_read,
|
|
||||||
.llseek = seq_lseek,
|
|
||||||
.release = single_release,
|
|
||||||
.owner = THIS_MODULE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int ab8500_gpadc_bk_bat_v_print(struct seq_file *s, void *p)
|
|
||||||
{
|
{
|
||||||
int bk_bat_v_raw;
|
int bk_bat_v_raw;
|
||||||
int bk_bat_v_convert;
|
int bk_bat_v_convert;
|
||||||
|
@ -2032,21 +1886,9 @@ static int ab8500_gpadc_bk_bat_v_print(struct seq_file *s, void *p)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ab8500_gpadc_bk_bat_v_open(struct inode *inode, struct file *file)
|
DEFINE_SHOW_ATTRIBUTE(ab8500_gpadc_bk_bat_v);
|
||||||
{
|
|
||||||
return single_open(file, ab8500_gpadc_bk_bat_v_print,
|
|
||||||
inode->i_private);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct file_operations ab8500_gpadc_bk_bat_v_fops = {
|
static int ab8500_gpadc_die_temp_show(struct seq_file *s, void *p)
|
||||||
.open = ab8500_gpadc_bk_bat_v_open,
|
|
||||||
.read = seq_read,
|
|
||||||
.llseek = seq_lseek,
|
|
||||||
.release = single_release,
|
|
||||||
.owner = THIS_MODULE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int ab8500_gpadc_die_temp_print(struct seq_file *s, void *p)
|
|
||||||
{
|
{
|
||||||
int die_temp_raw;
|
int die_temp_raw;
|
||||||
int die_temp_convert;
|
int die_temp_convert;
|
||||||
|
@ -2063,21 +1905,9 @@ static int ab8500_gpadc_die_temp_print(struct seq_file *s, void *p)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ab8500_gpadc_die_temp_open(struct inode *inode, struct file *file)
|
DEFINE_SHOW_ATTRIBUTE(ab8500_gpadc_die_temp);
|
||||||
{
|
|
||||||
return single_open(file, ab8500_gpadc_die_temp_print,
|
|
||||||
inode->i_private);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct file_operations ab8500_gpadc_die_temp_fops = {
|
static int ab8500_gpadc_usb_id_show(struct seq_file *s, void *p)
|
||||||
.open = ab8500_gpadc_die_temp_open,
|
|
||||||
.read = seq_read,
|
|
||||||
.llseek = seq_lseek,
|
|
||||||
.release = single_release,
|
|
||||||
.owner = THIS_MODULE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int ab8500_gpadc_usb_id_print(struct seq_file *s, void *p)
|
|
||||||
{
|
{
|
||||||
int usb_id_raw;
|
int usb_id_raw;
|
||||||
int usb_id_convert;
|
int usb_id_convert;
|
||||||
|
@ -2094,20 +1924,9 @@ static int ab8500_gpadc_usb_id_print(struct seq_file *s, void *p)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ab8500_gpadc_usb_id_open(struct inode *inode, struct file *file)
|
DEFINE_SHOW_ATTRIBUTE(ab8500_gpadc_usb_id);
|
||||||
{
|
|
||||||
return single_open(file, ab8500_gpadc_usb_id_print, inode->i_private);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct file_operations ab8500_gpadc_usb_id_fops = {
|
static int ab8540_gpadc_xtal_temp_show(struct seq_file *s, void *p)
|
||||||
.open = ab8500_gpadc_usb_id_open,
|
|
||||||
.read = seq_read,
|
|
||||||
.llseek = seq_lseek,
|
|
||||||
.release = single_release,
|
|
||||||
.owner = THIS_MODULE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int ab8540_gpadc_xtal_temp_print(struct seq_file *s, void *p)
|
|
||||||
{
|
{
|
||||||
int xtal_temp_raw;
|
int xtal_temp_raw;
|
||||||
int xtal_temp_convert;
|
int xtal_temp_convert;
|
||||||
|
@ -2124,21 +1943,9 @@ static int ab8540_gpadc_xtal_temp_print(struct seq_file *s, void *p)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ab8540_gpadc_xtal_temp_open(struct inode *inode, struct file *file)
|
DEFINE_SHOW_ATTRIBUTE(ab8540_gpadc_xtal_temp);
|
||||||
{
|
|
||||||
return single_open(file, ab8540_gpadc_xtal_temp_print,
|
|
||||||
inode->i_private);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct file_operations ab8540_gpadc_xtal_temp_fops = {
|
static int ab8540_gpadc_vbat_true_meas_show(struct seq_file *s, void *p)
|
||||||
.open = ab8540_gpadc_xtal_temp_open,
|
|
||||||
.read = seq_read,
|
|
||||||
.llseek = seq_lseek,
|
|
||||||
.release = single_release,
|
|
||||||
.owner = THIS_MODULE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int ab8540_gpadc_vbat_true_meas_print(struct seq_file *s, void *p)
|
|
||||||
{
|
{
|
||||||
int vbat_true_meas_raw;
|
int vbat_true_meas_raw;
|
||||||
int vbat_true_meas_convert;
|
int vbat_true_meas_convert;
|
||||||
|
@ -2156,22 +1963,9 @@ static int ab8540_gpadc_vbat_true_meas_print(struct seq_file *s, void *p)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ab8540_gpadc_vbat_true_meas_open(struct inode *inode,
|
DEFINE_SHOW_ATTRIBUTE(ab8540_gpadc_vbat_true_meas);
|
||||||
struct file *file)
|
|
||||||
{
|
|
||||||
return single_open(file, ab8540_gpadc_vbat_true_meas_print,
|
|
||||||
inode->i_private);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct file_operations ab8540_gpadc_vbat_true_meas_fops = {
|
static int ab8540_gpadc_bat_ctrl_and_ibat_show(struct seq_file *s, void *p)
|
||||||
.open = ab8540_gpadc_vbat_true_meas_open,
|
|
||||||
.read = seq_read,
|
|
||||||
.llseek = seq_lseek,
|
|
||||||
.release = single_release,
|
|
||||||
.owner = THIS_MODULE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int ab8540_gpadc_bat_ctrl_and_ibat_print(struct seq_file *s, void *p)
|
|
||||||
{
|
{
|
||||||
int bat_ctrl_raw;
|
int bat_ctrl_raw;
|
||||||
int bat_ctrl_convert;
|
int bat_ctrl_convert;
|
||||||
|
@ -2197,22 +1991,9 @@ static int ab8540_gpadc_bat_ctrl_and_ibat_print(struct seq_file *s, void *p)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ab8540_gpadc_bat_ctrl_and_ibat_open(struct inode *inode,
|
DEFINE_SHOW_ATTRIBUTE(ab8540_gpadc_bat_ctrl_and_ibat);
|
||||||
struct file *file)
|
|
||||||
{
|
|
||||||
return single_open(file, ab8540_gpadc_bat_ctrl_and_ibat_print,
|
|
||||||
inode->i_private);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct file_operations ab8540_gpadc_bat_ctrl_and_ibat_fops = {
|
static int ab8540_gpadc_vbat_meas_and_ibat_show(struct seq_file *s, void *p)
|
||||||
.open = ab8540_gpadc_bat_ctrl_and_ibat_open,
|
|
||||||
.read = seq_read,
|
|
||||||
.llseek = seq_lseek,
|
|
||||||
.release = single_release,
|
|
||||||
.owner = THIS_MODULE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int ab8540_gpadc_vbat_meas_and_ibat_print(struct seq_file *s, void *p)
|
|
||||||
{
|
{
|
||||||
int vbat_meas_raw;
|
int vbat_meas_raw;
|
||||||
int vbat_meas_convert;
|
int vbat_meas_convert;
|
||||||
|
@ -2237,23 +2018,9 @@ static int ab8540_gpadc_vbat_meas_and_ibat_print(struct seq_file *s, void *p)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ab8540_gpadc_vbat_meas_and_ibat_open(struct inode *inode,
|
DEFINE_SHOW_ATTRIBUTE(ab8540_gpadc_vbat_meas_and_ibat);
|
||||||
struct file *file)
|
|
||||||
{
|
|
||||||
return single_open(file, ab8540_gpadc_vbat_meas_and_ibat_print,
|
|
||||||
inode->i_private);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct file_operations ab8540_gpadc_vbat_meas_and_ibat_fops = {
|
static int ab8540_gpadc_vbat_true_meas_and_ibat_show(struct seq_file *s, void *p)
|
||||||
.open = ab8540_gpadc_vbat_meas_and_ibat_open,
|
|
||||||
.read = seq_read,
|
|
||||||
.llseek = seq_lseek,
|
|
||||||
.release = single_release,
|
|
||||||
.owner = THIS_MODULE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int ab8540_gpadc_vbat_true_meas_and_ibat_print(struct seq_file *s,
|
|
||||||
void *p)
|
|
||||||
{
|
{
|
||||||
int vbat_true_meas_raw;
|
int vbat_true_meas_raw;
|
||||||
int vbat_true_meas_convert;
|
int vbat_true_meas_convert;
|
||||||
|
@ -2279,23 +2046,9 @@ static int ab8540_gpadc_vbat_true_meas_and_ibat_print(struct seq_file *s,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ab8540_gpadc_vbat_true_meas_and_ibat_open(struct inode *inode,
|
DEFINE_SHOW_ATTRIBUTE(ab8540_gpadc_vbat_true_meas_and_ibat);
|
||||||
struct file *file)
|
|
||||||
{
|
|
||||||
return single_open(file, ab8540_gpadc_vbat_true_meas_and_ibat_print,
|
|
||||||
inode->i_private);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct file_operations
|
static int ab8540_gpadc_bat_temp_and_ibat_show(struct seq_file *s, void *p)
|
||||||
ab8540_gpadc_vbat_true_meas_and_ibat_fops = {
|
|
||||||
.open = ab8540_gpadc_vbat_true_meas_and_ibat_open,
|
|
||||||
.read = seq_read,
|
|
||||||
.llseek = seq_lseek,
|
|
||||||
.release = single_release,
|
|
||||||
.owner = THIS_MODULE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int ab8540_gpadc_bat_temp_and_ibat_print(struct seq_file *s, void *p)
|
|
||||||
{
|
{
|
||||||
int bat_temp_raw;
|
int bat_temp_raw;
|
||||||
int bat_temp_convert;
|
int bat_temp_convert;
|
||||||
|
@ -2320,22 +2073,9 @@ static int ab8540_gpadc_bat_temp_and_ibat_print(struct seq_file *s, void *p)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ab8540_gpadc_bat_temp_and_ibat_open(struct inode *inode,
|
DEFINE_SHOW_ATTRIBUTE(ab8540_gpadc_bat_temp_and_ibat);
|
||||||
struct file *file)
|
|
||||||
{
|
|
||||||
return single_open(file, ab8540_gpadc_bat_temp_and_ibat_print,
|
|
||||||
inode->i_private);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct file_operations ab8540_gpadc_bat_temp_and_ibat_fops = {
|
static int ab8540_gpadc_otp_calib_show(struct seq_file *s, void *p)
|
||||||
.open = ab8540_gpadc_bat_temp_and_ibat_open,
|
|
||||||
.read = seq_read,
|
|
||||||
.llseek = seq_lseek,
|
|
||||||
.release = single_release,
|
|
||||||
.owner = THIS_MODULE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int ab8540_gpadc_otp_cal_print(struct seq_file *s, void *p)
|
|
||||||
{
|
{
|
||||||
struct ab8500_gpadc *gpadc;
|
struct ab8500_gpadc *gpadc;
|
||||||
u16 vmain_l, vmain_h, btemp_l, btemp_h;
|
u16 vmain_l, vmain_h, btemp_l, btemp_h;
|
||||||
|
@ -2359,18 +2099,7 @@ static int ab8540_gpadc_otp_cal_print(struct seq_file *s, void *p)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ab8540_gpadc_otp_cal_open(struct inode *inode, struct file *file)
|
DEFINE_SHOW_ATTRIBUTE(ab8540_gpadc_otp_calib);
|
||||||
{
|
|
||||||
return single_open(file, ab8540_gpadc_otp_cal_print, inode->i_private);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct file_operations ab8540_gpadc_otp_calib_fops = {
|
|
||||||
.open = ab8540_gpadc_otp_cal_open,
|
|
||||||
.read = seq_read,
|
|
||||||
.llseek = seq_lseek,
|
|
||||||
.release = single_release,
|
|
||||||
.owner = THIS_MODULE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int ab8500_gpadc_avg_sample_print(struct seq_file *s, void *p)
|
static int ab8500_gpadc_avg_sample_print(struct seq_file *s, void *p)
|
||||||
{
|
{
|
||||||
|
@ -2903,14 +2632,6 @@ static const struct file_operations ab8500_val_fops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct file_operations ab8500_interrupts_fops = {
|
|
||||||
.open = ab8500_interrupts_open,
|
|
||||||
.read = seq_read,
|
|
||||||
.llseek = seq_lseek,
|
|
||||||
.release = single_release,
|
|
||||||
.owner = THIS_MODULE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct file_operations ab8500_subscribe_fops = {
|
static const struct file_operations ab8500_subscribe_fops = {
|
||||||
.open = ab8500_subscribe_unsubscribe_open,
|
.open = ab8500_subscribe_unsubscribe_open,
|
||||||
.write = ab8500_subscribe_write,
|
.write = ab8500_subscribe_write,
|
||||||
|
@ -2997,7 +2718,7 @@ static int ab8500_debug_probe(struct platform_device *plf)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
file = debugfs_create_file("all-bank-registers", S_IRUGO, ab8500_dir,
|
file = debugfs_create_file("all-bank-registers", S_IRUGO, ab8500_dir,
|
||||||
&plf->dev, &ab8500_registers_fops);
|
&plf->dev, &ab8500_bank_registers_fops);
|
||||||
if (!file)
|
if (!file)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
|
|
@ -39,34 +39,43 @@
|
||||||
#define FLEX_MR_OPMODE(opmode) (((opmode) << FLEX_MR_OPMODE_OFFSET) & \
|
#define FLEX_MR_OPMODE(opmode) (((opmode) << FLEX_MR_OPMODE_OFFSET) & \
|
||||||
FLEX_MR_OPMODE_MASK)
|
FLEX_MR_OPMODE_MASK)
|
||||||
|
|
||||||
|
struct atmel_flexcom {
|
||||||
|
void __iomem *base;
|
||||||
|
u32 opmode;
|
||||||
|
struct clk *clk;
|
||||||
|
};
|
||||||
|
|
||||||
static int atmel_flexcom_probe(struct platform_device *pdev)
|
static int atmel_flexcom_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct device_node *np = pdev->dev.of_node;
|
struct device_node *np = pdev->dev.of_node;
|
||||||
struct clk *clk;
|
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
void __iomem *base;
|
struct atmel_flexcom *ddata;
|
||||||
u32 opmode;
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = of_property_read_u32(np, "atmel,flexcom-mode", &opmode);
|
ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
|
||||||
|
if (!ddata)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
platform_set_drvdata(pdev, ddata);
|
||||||
|
|
||||||
|
err = of_property_read_u32(np, "atmel,flexcom-mode", &ddata->opmode);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
if (opmode < ATMEL_FLEXCOM_MODE_USART ||
|
if (ddata->opmode < ATMEL_FLEXCOM_MODE_USART ||
|
||||||
opmode > ATMEL_FLEXCOM_MODE_TWI)
|
ddata->opmode > ATMEL_FLEXCOM_MODE_TWI)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
base = devm_ioremap_resource(&pdev->dev, res);
|
ddata->base = devm_ioremap_resource(&pdev->dev, res);
|
||||||
if (IS_ERR(base))
|
if (IS_ERR(ddata->base))
|
||||||
return PTR_ERR(base);
|
return PTR_ERR(ddata->base);
|
||||||
|
|
||||||
clk = devm_clk_get(&pdev->dev, NULL);
|
ddata->clk = devm_clk_get(&pdev->dev, NULL);
|
||||||
if (IS_ERR(clk))
|
if (IS_ERR(ddata->clk))
|
||||||
return PTR_ERR(clk);
|
return PTR_ERR(ddata->clk);
|
||||||
|
|
||||||
err = clk_prepare_enable(clk);
|
err = clk_prepare_enable(ddata->clk);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
@ -76,9 +85,9 @@ static int atmel_flexcom_probe(struct platform_device *pdev)
|
||||||
* inaccessible and are read as zero. Also the external I/O lines of the
|
* inaccessible and are read as zero. Also the external I/O lines of the
|
||||||
* Flexcom are muxed to reach the selected device.
|
* Flexcom are muxed to reach the selected device.
|
||||||
*/
|
*/
|
||||||
writel(FLEX_MR_OPMODE(opmode), base + FLEX_MR);
|
writel(FLEX_MR_OPMODE(ddata->opmode), ddata->base + FLEX_MR);
|
||||||
|
|
||||||
clk_disable_unprepare(clk);
|
clk_disable_unprepare(ddata->clk);
|
||||||
|
|
||||||
return devm_of_platform_populate(&pdev->dev);
|
return devm_of_platform_populate(&pdev->dev);
|
||||||
}
|
}
|
||||||
|
@ -89,10 +98,34 @@ static const struct of_device_id atmel_flexcom_of_match[] = {
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, atmel_flexcom_of_match);
|
MODULE_DEVICE_TABLE(of, atmel_flexcom_of_match);
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM_SLEEP
|
||||||
|
static int atmel_flexcom_resume(struct device *dev)
|
||||||
|
{
|
||||||
|
struct atmel_flexcom *ddata = dev_get_drvdata(dev);
|
||||||
|
int err;
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
err = clk_prepare_enable(ddata->clk);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
val = FLEX_MR_OPMODE(ddata->opmode),
|
||||||
|
writel(val, ddata->base + FLEX_MR);
|
||||||
|
|
||||||
|
clk_disable_unprepare(ddata->clk);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static SIMPLE_DEV_PM_OPS(atmel_flexcom_pm_ops, NULL,
|
||||||
|
atmel_flexcom_resume);
|
||||||
|
|
||||||
static struct platform_driver atmel_flexcom_driver = {
|
static struct platform_driver atmel_flexcom_driver = {
|
||||||
.probe = atmel_flexcom_probe,
|
.probe = atmel_flexcom_probe,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "atmel_flexcom",
|
.name = "atmel_flexcom",
|
||||||
|
.pm = &atmel_flexcom_pm_ops,
|
||||||
.of_match_table = atmel_flexcom_of_match,
|
.of_match_table = atmel_flexcom_of_match,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -129,6 +129,7 @@ static const struct regmap_range axp288_volatile_ranges[] = {
|
||||||
regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP288_POWER_REASON),
|
regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP288_POWER_REASON),
|
||||||
regmap_reg_range(AXP288_BC_GLOBAL, AXP288_BC_GLOBAL),
|
regmap_reg_range(AXP288_BC_GLOBAL, AXP288_BC_GLOBAL),
|
||||||
regmap_reg_range(AXP288_BC_DET_STAT, AXP288_BC_DET_STAT),
|
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(AXP20X_IRQ1_EN, AXP20X_IPSOUT_V_HIGH_L),
|
regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IPSOUT_V_HIGH_L),
|
||||||
regmap_reg_range(AXP20X_TIMER_CTRL, AXP20X_TIMER_CTRL),
|
regmap_reg_range(AXP20X_TIMER_CTRL, AXP20X_TIMER_CTRL),
|
||||||
regmap_reg_range(AXP22X_GPIO_STATE, AXP22X_GPIO_STATE),
|
regmap_reg_range(AXP22X_GPIO_STATE, AXP22X_GPIO_STATE),
|
||||||
|
@ -878,6 +879,9 @@ static struct mfd_cell axp813_cells[] = {
|
||||||
.resources = axp803_pek_resources,
|
.resources = axp803_pek_resources,
|
||||||
}, {
|
}, {
|
||||||
.name = "axp20x-regulator",
|
.name = "axp20x-regulator",
|
||||||
|
}, {
|
||||||
|
.name = "axp20x-gpio",
|
||||||
|
.of_compatible = "x-powers,axp813-gpio",
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -40,13 +40,13 @@ static struct cros_ec_platform pd_p = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct mfd_cell ec_cell = {
|
static const struct mfd_cell ec_cell = {
|
||||||
.name = "cros-ec-ctl",
|
.name = "cros-ec-dev",
|
||||||
.platform_data = &ec_p,
|
.platform_data = &ec_p,
|
||||||
.pdata_size = sizeof(ec_p),
|
.pdata_size = sizeof(ec_p),
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct mfd_cell ec_pd_cell = {
|
static const struct mfd_cell ec_pd_cell = {
|
||||||
.name = "cros-ec-ctl",
|
.name = "cros-ec-dev",
|
||||||
.platform_data = &pd_p,
|
.platform_data = &pd_p,
|
||||||
.pdata_size = sizeof(pd_p),
|
.pdata_size = sizeof(pd_p),
|
||||||
};
|
};
|
||||||
|
|
|
@ -25,9 +25,10 @@
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
|
|
||||||
#include "cros_ec_debugfs.h"
|
|
||||||
#include "cros_ec_dev.h"
|
#include "cros_ec_dev.h"
|
||||||
|
|
||||||
|
#define DRV_NAME "cros-ec-dev"
|
||||||
|
|
||||||
/* Device variables */
|
/* Device variables */
|
||||||
#define CROS_MAX_DEV 128
|
#define CROS_MAX_DEV 128
|
||||||
static int ec_major;
|
static int ec_major;
|
||||||
|
@ -461,7 +462,7 @@ static int ec_device_remove(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct platform_device_id cros_ec_id[] = {
|
static const struct platform_device_id cros_ec_id[] = {
|
||||||
{ "cros-ec-ctl", 0 },
|
{ DRV_NAME, 0 },
|
||||||
{ /* sentinel */ },
|
{ /* sentinel */ },
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(platform, cros_ec_id);
|
MODULE_DEVICE_TABLE(platform, cros_ec_id);
|
||||||
|
@ -493,7 +494,7 @@ static const struct dev_pm_ops cros_ec_dev_pm_ops = {
|
||||||
|
|
||||||
static struct platform_driver cros_ec_dev_driver = {
|
static struct platform_driver cros_ec_dev_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "cros-ec-ctl",
|
.name = DRV_NAME,
|
||||||
.pm = &cros_ec_dev_pm_ops,
|
.pm = &cros_ec_dev_pm_ops,
|
||||||
},
|
},
|
||||||
.probe = ec_device_probe,
|
.probe = ec_device_probe,
|
||||||
|
@ -544,6 +545,7 @@ static void __exit cros_ec_dev_exit(void)
|
||||||
module_init(cros_ec_dev_init);
|
module_init(cros_ec_dev_init);
|
||||||
module_exit(cros_ec_dev_exit);
|
module_exit(cros_ec_dev_exit);
|
||||||
|
|
||||||
|
MODULE_ALIAS("platform:" DRV_NAME);
|
||||||
MODULE_AUTHOR("Bill Richardson <wfrichar@chromium.org>");
|
MODULE_AUTHOR("Bill Richardson <wfrichar@chromium.org>");
|
||||||
MODULE_DESCRIPTION("Userspace interface to the Chrome OS Embedded Controller");
|
MODULE_DESCRIPTION("Userspace interface to the Chrome OS Embedded Controller");
|
||||||
MODULE_VERSION("1.0");
|
MODULE_VERSION("1.0");
|
|
@ -72,8 +72,7 @@
|
||||||
* struct cros_ec_spi - information about a SPI-connected EC
|
* struct cros_ec_spi - information about a SPI-connected EC
|
||||||
*
|
*
|
||||||
* @spi: SPI device we are connected to
|
* @spi: SPI device we are connected to
|
||||||
* @last_transfer_ns: time that we last finished a transfer, or 0 if there
|
* @last_transfer_ns: time that we last finished a transfer.
|
||||||
* if no record
|
|
||||||
* @start_of_msg_delay: used to set the delay_usecs on the spi_transfer that
|
* @start_of_msg_delay: used to set the delay_usecs on the spi_transfer that
|
||||||
* is sent when we want to turn on CS at the start of a transaction.
|
* is sent when we want to turn on CS at the start of a transaction.
|
||||||
* @end_of_msg_delay: used to set the delay_usecs on the spi_transfer that
|
* @end_of_msg_delay: used to set the delay_usecs on the spi_transfer that
|
||||||
|
@ -379,18 +378,15 @@ static int cros_ec_pkt_xfer_spi(struct cros_ec_device *ec_dev,
|
||||||
u8 sum;
|
u8 sum;
|
||||||
u8 rx_byte;
|
u8 rx_byte;
|
||||||
int ret = 0, final_ret;
|
int ret = 0, final_ret;
|
||||||
|
unsigned long delay;
|
||||||
|
|
||||||
len = cros_ec_prepare_tx(ec_dev, ec_msg);
|
len = cros_ec_prepare_tx(ec_dev, ec_msg);
|
||||||
dev_dbg(ec_dev->dev, "prepared, len=%d\n", len);
|
dev_dbg(ec_dev->dev, "prepared, len=%d\n", len);
|
||||||
|
|
||||||
/* If it's too soon to do another transaction, wait */
|
/* If it's too soon to do another transaction, wait */
|
||||||
if (ec_spi->last_transfer_ns) {
|
delay = ktime_get_ns() - ec_spi->last_transfer_ns;
|
||||||
unsigned long delay; /* The delay completed so far */
|
if (delay < EC_SPI_RECOVERY_TIME_NS)
|
||||||
|
ndelay(EC_SPI_RECOVERY_TIME_NS - delay);
|
||||||
delay = ktime_get_ns() - ec_spi->last_transfer_ns;
|
|
||||||
if (delay < EC_SPI_RECOVERY_TIME_NS)
|
|
||||||
ndelay(EC_SPI_RECOVERY_TIME_NS - delay);
|
|
||||||
}
|
|
||||||
|
|
||||||
rx_buf = kzalloc(len, GFP_KERNEL);
|
rx_buf = kzalloc(len, GFP_KERNEL);
|
||||||
if (!rx_buf)
|
if (!rx_buf)
|
||||||
|
@ -509,18 +505,15 @@ static int cros_ec_cmd_xfer_spi(struct cros_ec_device *ec_dev,
|
||||||
u8 rx_byte;
|
u8 rx_byte;
|
||||||
int sum;
|
int sum;
|
||||||
int ret = 0, final_ret;
|
int ret = 0, final_ret;
|
||||||
|
unsigned long delay;
|
||||||
|
|
||||||
len = cros_ec_prepare_tx(ec_dev, ec_msg);
|
len = cros_ec_prepare_tx(ec_dev, ec_msg);
|
||||||
dev_dbg(ec_dev->dev, "prepared, len=%d\n", len);
|
dev_dbg(ec_dev->dev, "prepared, len=%d\n", len);
|
||||||
|
|
||||||
/* If it's too soon to do another transaction, wait */
|
/* If it's too soon to do another transaction, wait */
|
||||||
if (ec_spi->last_transfer_ns) {
|
delay = ktime_get_ns() - ec_spi->last_transfer_ns;
|
||||||
unsigned long delay; /* The delay completed so far */
|
if (delay < EC_SPI_RECOVERY_TIME_NS)
|
||||||
|
ndelay(EC_SPI_RECOVERY_TIME_NS - delay);
|
||||||
delay = ktime_get_ns() - ec_spi->last_transfer_ns;
|
|
||||||
if (delay < EC_SPI_RECOVERY_TIME_NS)
|
|
||||||
ndelay(EC_SPI_RECOVERY_TIME_NS - delay);
|
|
||||||
}
|
|
||||||
|
|
||||||
rx_buf = kzalloc(len, GFP_KERNEL);
|
rx_buf = kzalloc(len, GFP_KERNEL);
|
||||||
if (!rx_buf)
|
if (!rx_buf)
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
* Author: Zhu, Lejun <lejun.zhu@linux.intel.com>
|
* Author: Zhu, Lejun <lejun.zhu@linux.intel.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/acpi.h>
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/mfd/core.h>
|
#include <linux/mfd/core.h>
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
|
|
|
@ -458,7 +458,7 @@ static int kempld_probe(struct platform_device *pdev)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
pld->io_base = devm_ioport_map(dev, ioport->start,
|
pld->io_base = devm_ioport_map(dev, ioport->start,
|
||||||
ioport->end - ioport->start);
|
resource_size(ioport));
|
||||||
if (!pld->io_base)
|
if (!pld->io_base)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
|
|
@ -1143,11 +1143,6 @@ static int lpc_ich_init_spi(struct pci_dev *dev)
|
||||||
res->end = res->start + SPIBASE_APL_SZ - 1;
|
res->end = res->start + SPIBASE_APL_SZ - 1;
|
||||||
|
|
||||||
pci_bus_read_config_dword(bus, spi, BCR, &bcr);
|
pci_bus_read_config_dword(bus, spi, BCR, &bcr);
|
||||||
if (!(bcr & BCR_WPD)) {
|
|
||||||
bcr |= BCR_WPD;
|
|
||||||
pci_bus_write_config_dword(bus, spi, BCR, bcr);
|
|
||||||
pci_bus_read_config_dword(bus, spi, BCR, &bcr);
|
|
||||||
}
|
|
||||||
info->writeable = !!(bcr & BCR_WPD);
|
info->writeable = !!(bcr & BCR_WPD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/mfd/core.h>
|
#include <linux/mfd/core.h>
|
||||||
#include <linux/mfd/max77693-common.h>
|
#include <linux/mfd/max77693-common.h>
|
||||||
#include <linux/mfd/max77843-private.h>
|
#include <linux/mfd/max77843-private.h>
|
||||||
|
|
|
@ -430,6 +430,7 @@ static void palmas_power_off(void)
|
||||||
{
|
{
|
||||||
unsigned int addr;
|
unsigned int addr;
|
||||||
int ret, slave;
|
int ret, slave;
|
||||||
|
u8 powerhold_mask;
|
||||||
struct device_node *np = palmas_dev->dev->of_node;
|
struct device_node *np = palmas_dev->dev->of_node;
|
||||||
|
|
||||||
if (of_property_read_bool(np, "ti,palmas-override-powerhold")) {
|
if (of_property_read_bool(np, "ti,palmas-override-powerhold")) {
|
||||||
|
@ -437,8 +438,15 @@ static void palmas_power_off(void)
|
||||||
PALMAS_PRIMARY_SECONDARY_PAD2);
|
PALMAS_PRIMARY_SECONDARY_PAD2);
|
||||||
slave = PALMAS_BASE_TO_SLAVE(PALMAS_PU_PD_OD_BASE);
|
slave = PALMAS_BASE_TO_SLAVE(PALMAS_PU_PD_OD_BASE);
|
||||||
|
|
||||||
|
if (of_device_is_compatible(np, "ti,tps65917"))
|
||||||
|
powerhold_mask =
|
||||||
|
TPS65917_PRIMARY_SECONDARY_PAD2_GPIO_5_MASK;
|
||||||
|
else
|
||||||
|
powerhold_mask =
|
||||||
|
PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_7_MASK;
|
||||||
|
|
||||||
ret = regmap_update_bits(palmas_dev->regmap[slave], addr,
|
ret = regmap_update_bits(palmas_dev->regmap[slave], addr,
|
||||||
PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_7_MASK, 0);
|
powerhold_mask, 0);
|
||||||
if (ret)
|
if (ret)
|
||||||
dev_err(palmas_dev->dev,
|
dev_err(palmas_dev->dev,
|
||||||
"Unable to write PRIMARY_SECONDARY_PAD2 %d\n",
|
"Unable to write PRIMARY_SECONDARY_PAD2 %d\n",
|
||||||
|
|
|
@ -149,7 +149,7 @@ pcf50633_client_dev_register(struct pcf50633 *pcf, const char *name,
|
||||||
|
|
||||||
*pdev = platform_device_alloc(name, -1);
|
*pdev = platform_device_alloc(name, -1);
|
||||||
if (!*pdev) {
|
if (!*pdev) {
|
||||||
dev_err(pcf->dev, "Falied to allocate %s\n", name);
|
dev_err(pcf->dev, "Failed to allocate %s\n", name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,710 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Multifunction core driver for Zodiac Inflight Innovations RAVE
|
||||||
|
* Supervisory Processor(SP) MCU that is connected via dedicated UART
|
||||||
|
* port
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 Zodiac Inflight Innovations
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/atomic.h>
|
||||||
|
#include <linux/crc-ccitt.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
|
#include <linux/export.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/mfd/rave-sp.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/of_device.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
#include <linux/serdev.h>
|
||||||
|
#include <asm/unaligned.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* UART protocol using following entities:
|
||||||
|
* - message to MCU => ACK response
|
||||||
|
* - event from MCU => event ACK
|
||||||
|
*
|
||||||
|
* Frame structure:
|
||||||
|
* <STX> <DATA> <CHECKSUM> <ETX>
|
||||||
|
* Where:
|
||||||
|
* - STX - is start of transmission character
|
||||||
|
* - ETX - end of transmission
|
||||||
|
* - DATA - payload
|
||||||
|
* - CHECKSUM - checksum calculated on <DATA>
|
||||||
|
*
|
||||||
|
* If <DATA> or <CHECKSUM> contain one of control characters, then it is
|
||||||
|
* escaped using <DLE> control code. Added <DLE> does not participate in
|
||||||
|
* checksum calculation.
|
||||||
|
*/
|
||||||
|
#define RAVE_SP_STX 0x02
|
||||||
|
#define RAVE_SP_ETX 0x03
|
||||||
|
#define RAVE_SP_DLE 0x10
|
||||||
|
|
||||||
|
#define RAVE_SP_MAX_DATA_SIZE 64
|
||||||
|
#define RAVE_SP_CHECKSUM_SIZE 2 /* Worst case scenario on RDU2 */
|
||||||
|
/*
|
||||||
|
* We don't store STX, ETX and unescaped bytes, so Rx is only
|
||||||
|
* DATA + CSUM
|
||||||
|
*/
|
||||||
|
#define RAVE_SP_RX_BUFFER_SIZE \
|
||||||
|
(RAVE_SP_MAX_DATA_SIZE + RAVE_SP_CHECKSUM_SIZE)
|
||||||
|
|
||||||
|
#define RAVE_SP_STX_ETX_SIZE 2
|
||||||
|
/*
|
||||||
|
* For Tx we have to have space for everything, STX, EXT and
|
||||||
|
* potentially stuffed DATA + CSUM data + csum
|
||||||
|
*/
|
||||||
|
#define RAVE_SP_TX_BUFFER_SIZE \
|
||||||
|
(RAVE_SP_STX_ETX_SIZE + 2 * RAVE_SP_RX_BUFFER_SIZE)
|
||||||
|
|
||||||
|
#define RAVE_SP_BOOT_SOURCE_GET 0
|
||||||
|
#define RAVE_SP_BOOT_SOURCE_SET 1
|
||||||
|
|
||||||
|
#define RAVE_SP_RDU2_BOARD_TYPE_RMB 0
|
||||||
|
#define RAVE_SP_RDU2_BOARD_TYPE_DEB 1
|
||||||
|
|
||||||
|
#define RAVE_SP_BOOT_SOURCE_SD 0
|
||||||
|
#define RAVE_SP_BOOT_SOURCE_EMMC 1
|
||||||
|
#define RAVE_SP_BOOT_SOURCE_NOR 2
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum rave_sp_deframer_state - Possible state for de-framer
|
||||||
|
*
|
||||||
|
* @RAVE_SP_EXPECT_SOF: Scanning input for start-of-frame marker
|
||||||
|
* @RAVE_SP_EXPECT_DATA: Got start of frame marker, collecting frame
|
||||||
|
* @RAVE_SP_EXPECT_ESCAPED_DATA: Got escape character, collecting escaped byte
|
||||||
|
*/
|
||||||
|
enum rave_sp_deframer_state {
|
||||||
|
RAVE_SP_EXPECT_SOF,
|
||||||
|
RAVE_SP_EXPECT_DATA,
|
||||||
|
RAVE_SP_EXPECT_ESCAPED_DATA,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct rave_sp_deframer - Device protocol deframer
|
||||||
|
*
|
||||||
|
* @state: Current state of the deframer
|
||||||
|
* @data: Buffer used to collect deframed data
|
||||||
|
* @length: Number of bytes de-framed so far
|
||||||
|
*/
|
||||||
|
struct rave_sp_deframer {
|
||||||
|
enum rave_sp_deframer_state state;
|
||||||
|
unsigned char data[RAVE_SP_RX_BUFFER_SIZE];
|
||||||
|
size_t length;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct rave_sp_reply - Reply as per RAVE device protocol
|
||||||
|
*
|
||||||
|
* @length: Expected reply length
|
||||||
|
* @data: Buffer to store reply payload in
|
||||||
|
* @code: Expected reply code
|
||||||
|
* @ackid: Expected reply ACK ID
|
||||||
|
* @completion: Successful reply reception completion
|
||||||
|
*/
|
||||||
|
struct rave_sp_reply {
|
||||||
|
size_t length;
|
||||||
|
void *data;
|
||||||
|
u8 code;
|
||||||
|
u8 ackid;
|
||||||
|
struct completion received;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct rave_sp_checksum - Variant specific checksum implementation details
|
||||||
|
*
|
||||||
|
* @length: Caculated checksum length
|
||||||
|
* @subroutine: Utilized checksum algorithm implementation
|
||||||
|
*/
|
||||||
|
struct rave_sp_checksum {
|
||||||
|
size_t length;
|
||||||
|
void (*subroutine)(const u8 *, size_t, u8 *);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct rave_sp_variant_cmds - Variant specific command routines
|
||||||
|
*
|
||||||
|
* @translate: Generic to variant specific command mapping routine
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
struct rave_sp_variant_cmds {
|
||||||
|
int (*translate)(enum rave_sp_command);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct rave_sp_variant - RAVE supervisory processor core variant
|
||||||
|
*
|
||||||
|
* @checksum: Variant specific checksum implementation
|
||||||
|
* @cmd: Variant specific command pointer table
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
struct rave_sp_variant {
|
||||||
|
const struct rave_sp_checksum *checksum;
|
||||||
|
struct rave_sp_variant_cmds cmd;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct rave_sp - RAVE supervisory processor core
|
||||||
|
*
|
||||||
|
* @serdev: Pointer to underlying serdev
|
||||||
|
* @deframer: Stored state of the protocol deframer
|
||||||
|
* @ackid: ACK ID used in last reply sent to the device
|
||||||
|
* @bus_lock: Lock to serialize access to the device
|
||||||
|
* @reply_lock: Lock protecting @reply
|
||||||
|
* @reply: Pointer to memory to store reply payload
|
||||||
|
*
|
||||||
|
* @variant: Device variant specific information
|
||||||
|
* @event_notifier_list: Input event notification chain
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
struct rave_sp {
|
||||||
|
struct serdev_device *serdev;
|
||||||
|
struct rave_sp_deframer deframer;
|
||||||
|
atomic_t ackid;
|
||||||
|
struct mutex bus_lock;
|
||||||
|
struct mutex reply_lock;
|
||||||
|
struct rave_sp_reply *reply;
|
||||||
|
|
||||||
|
const struct rave_sp_variant *variant;
|
||||||
|
struct blocking_notifier_head event_notifier_list;
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool rave_sp_id_is_event(u8 code)
|
||||||
|
{
|
||||||
|
return (code & 0xF0) == RAVE_SP_EVNT_BASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rave_sp_unregister_event_notifier(struct device *dev, void *res)
|
||||||
|
{
|
||||||
|
struct rave_sp *sp = dev_get_drvdata(dev->parent);
|
||||||
|
struct notifier_block *nb = *(struct notifier_block **)res;
|
||||||
|
struct blocking_notifier_head *bnh = &sp->event_notifier_list;
|
||||||
|
|
||||||
|
WARN_ON(blocking_notifier_chain_unregister(bnh, nb));
|
||||||
|
}
|
||||||
|
|
||||||
|
int devm_rave_sp_register_event_notifier(struct device *dev,
|
||||||
|
struct notifier_block *nb)
|
||||||
|
{
|
||||||
|
struct rave_sp *sp = dev_get_drvdata(dev->parent);
|
||||||
|
struct notifier_block **rcnb;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
rcnb = devres_alloc(rave_sp_unregister_event_notifier,
|
||||||
|
sizeof(*rcnb), GFP_KERNEL);
|
||||||
|
if (!rcnb)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
ret = blocking_notifier_chain_register(&sp->event_notifier_list, nb);
|
||||||
|
if (!ret) {
|
||||||
|
*rcnb = nb;
|
||||||
|
devres_add(dev, rcnb);
|
||||||
|
} else {
|
||||||
|
devres_free(rcnb);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(devm_rave_sp_register_event_notifier);
|
||||||
|
|
||||||
|
static void csum_8b2c(const u8 *buf, size_t size, u8 *crc)
|
||||||
|
{
|
||||||
|
*crc = *buf++;
|
||||||
|
size--;
|
||||||
|
|
||||||
|
while (size--)
|
||||||
|
*crc += *buf++;
|
||||||
|
|
||||||
|
*crc = 1 + ~(*crc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void csum_ccitt(const u8 *buf, size_t size, u8 *crc)
|
||||||
|
{
|
||||||
|
const u16 calculated = crc_ccitt_false(0xffff, buf, size);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* While the rest of the wire protocol is little-endian,
|
||||||
|
* CCITT-16 CRC in RDU2 device is sent out in big-endian order.
|
||||||
|
*/
|
||||||
|
put_unaligned_be16(calculated, crc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *stuff(unsigned char *dest, const unsigned char *src, size_t n)
|
||||||
|
{
|
||||||
|
while (n--) {
|
||||||
|
const unsigned char byte = *src++;
|
||||||
|
|
||||||
|
switch (byte) {
|
||||||
|
case RAVE_SP_STX:
|
||||||
|
case RAVE_SP_ETX:
|
||||||
|
case RAVE_SP_DLE:
|
||||||
|
*dest++ = RAVE_SP_DLE;
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
default:
|
||||||
|
*dest++ = byte;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rave_sp_write(struct rave_sp *sp, const u8 *data, u8 data_size)
|
||||||
|
{
|
||||||
|
const size_t checksum_length = sp->variant->checksum->length;
|
||||||
|
unsigned char frame[RAVE_SP_TX_BUFFER_SIZE];
|
||||||
|
unsigned char crc[RAVE_SP_CHECKSUM_SIZE];
|
||||||
|
unsigned char *dest = frame;
|
||||||
|
size_t length;
|
||||||
|
|
||||||
|
if (WARN_ON(checksum_length > sizeof(crc)))
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
if (WARN_ON(data_size > sizeof(frame)))
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
sp->variant->checksum->subroutine(data, data_size, crc);
|
||||||
|
|
||||||
|
*dest++ = RAVE_SP_STX;
|
||||||
|
dest = stuff(dest, data, data_size);
|
||||||
|
dest = stuff(dest, crc, checksum_length);
|
||||||
|
*dest++ = RAVE_SP_ETX;
|
||||||
|
|
||||||
|
length = dest - frame;
|
||||||
|
|
||||||
|
print_hex_dump(KERN_DEBUG, "rave-sp tx: ", DUMP_PREFIX_NONE,
|
||||||
|
16, 1, frame, length, false);
|
||||||
|
|
||||||
|
return serdev_device_write(sp->serdev, frame, length, HZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u8 rave_sp_reply_code(u8 command)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* There isn't a single rule that describes command code ->
|
||||||
|
* ACK code transformation, but, going through various
|
||||||
|
* versions of ICDs, there appear to be three distinct groups
|
||||||
|
* that can be described by simple transformation.
|
||||||
|
*/
|
||||||
|
switch (command) {
|
||||||
|
case 0xA0 ... 0xBE:
|
||||||
|
/*
|
||||||
|
* Commands implemented by firmware found in RDU1 and
|
||||||
|
* older devices all seem to obey the following rule
|
||||||
|
*/
|
||||||
|
return command + 0x20;
|
||||||
|
case 0xE0 ... 0xEF:
|
||||||
|
/*
|
||||||
|
* Events emitted by all versions of the firmare use
|
||||||
|
* least significant bit to get an ACK code
|
||||||
|
*/
|
||||||
|
return command | 0x01;
|
||||||
|
default:
|
||||||
|
/*
|
||||||
|
* Commands implemented by firmware found in RDU2 are
|
||||||
|
* similar to "old" commands, but they use slightly
|
||||||
|
* different offset
|
||||||
|
*/
|
||||||
|
return command + 0x40;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int rave_sp_exec(struct rave_sp *sp,
|
||||||
|
void *__data, size_t data_size,
|
||||||
|
void *reply_data, size_t reply_data_size)
|
||||||
|
{
|
||||||
|
struct rave_sp_reply reply = {
|
||||||
|
.data = reply_data,
|
||||||
|
.length = reply_data_size,
|
||||||
|
.received = COMPLETION_INITIALIZER_ONSTACK(reply.received),
|
||||||
|
};
|
||||||
|
unsigned char *data = __data;
|
||||||
|
int command, ret = 0;
|
||||||
|
u8 ackid;
|
||||||
|
|
||||||
|
command = sp->variant->cmd.translate(data[0]);
|
||||||
|
if (command < 0)
|
||||||
|
return command;
|
||||||
|
|
||||||
|
ackid = atomic_inc_return(&sp->ackid);
|
||||||
|
reply.ackid = ackid;
|
||||||
|
reply.code = rave_sp_reply_code((u8)command),
|
||||||
|
|
||||||
|
mutex_lock(&sp->bus_lock);
|
||||||
|
|
||||||
|
mutex_lock(&sp->reply_lock);
|
||||||
|
sp->reply = &reply;
|
||||||
|
mutex_unlock(&sp->reply_lock);
|
||||||
|
|
||||||
|
data[0] = command;
|
||||||
|
data[1] = ackid;
|
||||||
|
|
||||||
|
rave_sp_write(sp, data, data_size);
|
||||||
|
|
||||||
|
if (!wait_for_completion_timeout(&reply.received, HZ)) {
|
||||||
|
dev_err(&sp->serdev->dev, "Command timeout\n");
|
||||||
|
ret = -ETIMEDOUT;
|
||||||
|
|
||||||
|
mutex_lock(&sp->reply_lock);
|
||||||
|
sp->reply = NULL;
|
||||||
|
mutex_unlock(&sp->reply_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_unlock(&sp->bus_lock);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(rave_sp_exec);
|
||||||
|
|
||||||
|
static void rave_sp_receive_event(struct rave_sp *sp,
|
||||||
|
const unsigned char *data, size_t length)
|
||||||
|
{
|
||||||
|
u8 cmd[] = {
|
||||||
|
[0] = rave_sp_reply_code(data[0]),
|
||||||
|
[1] = data[1],
|
||||||
|
};
|
||||||
|
|
||||||
|
rave_sp_write(sp, cmd, sizeof(cmd));
|
||||||
|
|
||||||
|
blocking_notifier_call_chain(&sp->event_notifier_list,
|
||||||
|
rave_sp_action_pack(data[0], data[2]),
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rave_sp_receive_reply(struct rave_sp *sp,
|
||||||
|
const unsigned char *data, size_t length)
|
||||||
|
{
|
||||||
|
struct device *dev = &sp->serdev->dev;
|
||||||
|
struct rave_sp_reply *reply;
|
||||||
|
const size_t payload_length = length - 2;
|
||||||
|
|
||||||
|
mutex_lock(&sp->reply_lock);
|
||||||
|
reply = sp->reply;
|
||||||
|
|
||||||
|
if (reply) {
|
||||||
|
if (reply->code == data[0] && reply->ackid == data[1] &&
|
||||||
|
payload_length >= reply->length) {
|
||||||
|
/*
|
||||||
|
* We are relying on memcpy(dst, src, 0) to be a no-op
|
||||||
|
* when handling commands that have a no-payload reply
|
||||||
|
*/
|
||||||
|
memcpy(reply->data, &data[2], reply->length);
|
||||||
|
complete(&reply->received);
|
||||||
|
sp->reply = NULL;
|
||||||
|
} else {
|
||||||
|
dev_err(dev, "Ignoring incorrect reply\n");
|
||||||
|
dev_dbg(dev, "Code: expected = 0x%08x received = 0x%08x\n",
|
||||||
|
reply->code, data[0]);
|
||||||
|
dev_dbg(dev, "ACK ID: expected = 0x%08x received = 0x%08x\n",
|
||||||
|
reply->ackid, data[1]);
|
||||||
|
dev_dbg(dev, "Length: expected = %zu received = %zu\n",
|
||||||
|
reply->length, payload_length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_unlock(&sp->reply_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rave_sp_receive_frame(struct rave_sp *sp,
|
||||||
|
const unsigned char *data,
|
||||||
|
size_t length)
|
||||||
|
{
|
||||||
|
const size_t checksum_length = sp->variant->checksum->length;
|
||||||
|
const size_t payload_length = length - checksum_length;
|
||||||
|
const u8 *crc_reported = &data[payload_length];
|
||||||
|
struct device *dev = &sp->serdev->dev;
|
||||||
|
u8 crc_calculated[checksum_length];
|
||||||
|
|
||||||
|
print_hex_dump(KERN_DEBUG, "rave-sp rx: ", DUMP_PREFIX_NONE,
|
||||||
|
16, 1, data, length, false);
|
||||||
|
|
||||||
|
if (unlikely(length <= checksum_length)) {
|
||||||
|
dev_warn(dev, "Dropping short frame\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sp->variant->checksum->subroutine(data, payload_length,
|
||||||
|
crc_calculated);
|
||||||
|
|
||||||
|
if (memcmp(crc_calculated, crc_reported, checksum_length)) {
|
||||||
|
dev_warn(dev, "Dropping bad frame\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rave_sp_id_is_event(data[0]))
|
||||||
|
rave_sp_receive_event(sp, data, length);
|
||||||
|
else
|
||||||
|
rave_sp_receive_reply(sp, data, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rave_sp_receive_buf(struct serdev_device *serdev,
|
||||||
|
const unsigned char *buf, size_t size)
|
||||||
|
{
|
||||||
|
struct device *dev = &serdev->dev;
|
||||||
|
struct rave_sp *sp = dev_get_drvdata(dev);
|
||||||
|
struct rave_sp_deframer *deframer = &sp->deframer;
|
||||||
|
const unsigned char *src = buf;
|
||||||
|
const unsigned char *end = buf + size;
|
||||||
|
|
||||||
|
while (src < end) {
|
||||||
|
const unsigned char byte = *src++;
|
||||||
|
|
||||||
|
switch (deframer->state) {
|
||||||
|
case RAVE_SP_EXPECT_SOF:
|
||||||
|
if (byte == RAVE_SP_STX)
|
||||||
|
deframer->state = RAVE_SP_EXPECT_DATA;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RAVE_SP_EXPECT_DATA:
|
||||||
|
/*
|
||||||
|
* Treat special byte values first
|
||||||
|
*/
|
||||||
|
switch (byte) {
|
||||||
|
case RAVE_SP_ETX:
|
||||||
|
rave_sp_receive_frame(sp,
|
||||||
|
deframer->data,
|
||||||
|
deframer->length);
|
||||||
|
/*
|
||||||
|
* Once we extracted a complete frame
|
||||||
|
* out of a stream, we call it done
|
||||||
|
* and proceed to bailing out while
|
||||||
|
* resetting the framer to initial
|
||||||
|
* state, regardless if we've consumed
|
||||||
|
* all of the stream or not.
|
||||||
|
*/
|
||||||
|
goto reset_framer;
|
||||||
|
case RAVE_SP_STX:
|
||||||
|
dev_warn(dev, "Bad frame: STX before ETX\n");
|
||||||
|
/*
|
||||||
|
* If we encounter second "start of
|
||||||
|
* the frame" marker before seeing
|
||||||
|
* corresponding "end of frame", we
|
||||||
|
* reset the framer and ignore both:
|
||||||
|
* frame started by first SOF and
|
||||||
|
* frame started by current SOF.
|
||||||
|
*
|
||||||
|
* NOTE: The above means that only the
|
||||||
|
* frame started by third SOF, sent
|
||||||
|
* after this one will have a chance
|
||||||
|
* to get throught.
|
||||||
|
*/
|
||||||
|
goto reset_framer;
|
||||||
|
case RAVE_SP_DLE:
|
||||||
|
deframer->state = RAVE_SP_EXPECT_ESCAPED_DATA;
|
||||||
|
/*
|
||||||
|
* If we encounter escape sequence we
|
||||||
|
* need to skip it and collect the
|
||||||
|
* byte that follows. We do it by
|
||||||
|
* forcing the next iteration of the
|
||||||
|
* encompassing while loop.
|
||||||
|
*/
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* For the rest of the bytes, that are not
|
||||||
|
* speical snoflakes, we do the same thing
|
||||||
|
* that we do to escaped data - collect it in
|
||||||
|
* deframer buffer
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
|
case RAVE_SP_EXPECT_ESCAPED_DATA:
|
||||||
|
deframer->data[deframer->length++] = byte;
|
||||||
|
|
||||||
|
if (deframer->length == sizeof(deframer->data)) {
|
||||||
|
dev_warn(dev, "Bad frame: Too long\n");
|
||||||
|
/*
|
||||||
|
* If the amount of data we've
|
||||||
|
* accumulated for current frame so
|
||||||
|
* far starts to exceed the capacity
|
||||||
|
* of deframer's buffer, there's
|
||||||
|
* nothing else we can do but to
|
||||||
|
* discard that data and start
|
||||||
|
* assemblying a new frame again
|
||||||
|
*/
|
||||||
|
goto reset_framer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We've extracted out special byte, now we
|
||||||
|
* can go back to regular data collecting
|
||||||
|
*/
|
||||||
|
deframer->state = RAVE_SP_EXPECT_DATA;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The only way to get out of the above loop and end up here
|
||||||
|
* is throught consuming all of the supplied data, so here we
|
||||||
|
* report that we processed it all.
|
||||||
|
*/
|
||||||
|
return size;
|
||||||
|
|
||||||
|
reset_framer:
|
||||||
|
/*
|
||||||
|
* NOTE: A number of codepaths that will drop us here will do
|
||||||
|
* so before consuming all 'size' bytes of the data passed by
|
||||||
|
* serdev layer. We rely on the fact that serdev layer will
|
||||||
|
* re-execute this handler with the remainder of the Rx bytes
|
||||||
|
* once we report actual number of bytes that we processed.
|
||||||
|
*/
|
||||||
|
deframer->state = RAVE_SP_EXPECT_SOF;
|
||||||
|
deframer->length = 0;
|
||||||
|
|
||||||
|
return src - buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rave_sp_rdu1_cmd_translate(enum rave_sp_command command)
|
||||||
|
{
|
||||||
|
if (command >= RAVE_SP_CMD_STATUS &&
|
||||||
|
command <= RAVE_SP_CMD_CONTROL_EVENTS)
|
||||||
|
return command;
|
||||||
|
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rave_sp_rdu2_cmd_translate(enum rave_sp_command command)
|
||||||
|
{
|
||||||
|
if (command >= RAVE_SP_CMD_GET_FIRMWARE_VERSION &&
|
||||||
|
command <= RAVE_SP_CMD_GET_GPIO_STATE)
|
||||||
|
return command;
|
||||||
|
|
||||||
|
if (command == RAVE_SP_CMD_REQ_COPPER_REV) {
|
||||||
|
/*
|
||||||
|
* As per RDU2 ICD 3.4.47 CMD_GET_COPPER_REV code is
|
||||||
|
* different from that for RDU1 and it is set to 0x28.
|
||||||
|
*/
|
||||||
|
return 0x28;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rave_sp_rdu1_cmd_translate(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rave_sp_default_cmd_translate(enum rave_sp_command command)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* All of the following command codes were taken from "Table :
|
||||||
|
* Communications Protocol Message Types" in section 3.3
|
||||||
|
* "MESSAGE TYPES" of Rave PIC24 ICD.
|
||||||
|
*/
|
||||||
|
switch (command) {
|
||||||
|
case RAVE_SP_CMD_GET_FIRMWARE_VERSION:
|
||||||
|
return 0x11;
|
||||||
|
case RAVE_SP_CMD_GET_BOOTLOADER_VERSION:
|
||||||
|
return 0x12;
|
||||||
|
case RAVE_SP_CMD_BOOT_SOURCE:
|
||||||
|
return 0x14;
|
||||||
|
case RAVE_SP_CMD_SW_WDT:
|
||||||
|
return 0x1C;
|
||||||
|
case RAVE_SP_CMD_RESET:
|
||||||
|
return 0x1E;
|
||||||
|
case RAVE_SP_CMD_RESET_REASON:
|
||||||
|
return 0x1F;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct rave_sp_checksum rave_sp_checksum_8b2c = {
|
||||||
|
.length = 1,
|
||||||
|
.subroutine = csum_8b2c,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct rave_sp_checksum rave_sp_checksum_ccitt = {
|
||||||
|
.length = 2,
|
||||||
|
.subroutine = csum_ccitt,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct rave_sp_variant rave_sp_legacy = {
|
||||||
|
.checksum = &rave_sp_checksum_8b2c,
|
||||||
|
.cmd = {
|
||||||
|
.translate = rave_sp_default_cmd_translate,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct rave_sp_variant rave_sp_rdu1 = {
|
||||||
|
.checksum = &rave_sp_checksum_8b2c,
|
||||||
|
.cmd = {
|
||||||
|
.translate = rave_sp_rdu1_cmd_translate,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct rave_sp_variant rave_sp_rdu2 = {
|
||||||
|
.checksum = &rave_sp_checksum_ccitt,
|
||||||
|
.cmd = {
|
||||||
|
.translate = rave_sp_rdu2_cmd_translate,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct of_device_id rave_sp_dt_ids[] = {
|
||||||
|
{ .compatible = "zii,rave-sp-niu", .data = &rave_sp_legacy },
|
||||||
|
{ .compatible = "zii,rave-sp-mezz", .data = &rave_sp_legacy },
|
||||||
|
{ .compatible = "zii,rave-sp-esb", .data = &rave_sp_legacy },
|
||||||
|
{ .compatible = "zii,rave-sp-rdu1", .data = &rave_sp_rdu1 },
|
||||||
|
{ .compatible = "zii,rave-sp-rdu2", .data = &rave_sp_rdu2 },
|
||||||
|
{ /* sentinel */ }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct serdev_device_ops rave_sp_serdev_device_ops = {
|
||||||
|
.receive_buf = rave_sp_receive_buf,
|
||||||
|
.write_wakeup = serdev_device_write_wakeup,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int rave_sp_probe(struct serdev_device *serdev)
|
||||||
|
{
|
||||||
|
struct device *dev = &serdev->dev;
|
||||||
|
struct rave_sp *sp;
|
||||||
|
u32 baud;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (of_property_read_u32(dev->of_node, "current-speed", &baud)) {
|
||||||
|
dev_err(dev,
|
||||||
|
"'current-speed' is not specified in device node\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
sp = devm_kzalloc(dev, sizeof(*sp), GFP_KERNEL);
|
||||||
|
if (!sp)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
sp->serdev = serdev;
|
||||||
|
dev_set_drvdata(dev, sp);
|
||||||
|
|
||||||
|
sp->variant = of_device_get_match_data(dev);
|
||||||
|
if (!sp->variant)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
mutex_init(&sp->bus_lock);
|
||||||
|
mutex_init(&sp->reply_lock);
|
||||||
|
BLOCKING_INIT_NOTIFIER_HEAD(&sp->event_notifier_list);
|
||||||
|
|
||||||
|
serdev_device_set_client_ops(serdev, &rave_sp_serdev_device_ops);
|
||||||
|
ret = devm_serdev_device_open(dev, serdev);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
serdev_device_set_baudrate(serdev, baud);
|
||||||
|
|
||||||
|
return devm_of_platform_populate(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
MODULE_DEVICE_TABLE(of, rave_sp_dt_ids);
|
||||||
|
|
||||||
|
static struct serdev_device_driver rave_sp_drv = {
|
||||||
|
.probe = rave_sp_probe,
|
||||||
|
.driver = {
|
||||||
|
.name = "rave-sp",
|
||||||
|
.of_match_table = rave_sp_dt_ids,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
module_serdev_device_driver(rave_sp_drv);
|
||||||
|
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_AUTHOR("Andrey Vostrikov <andrey.vostrikov@cogentembedded.com>");
|
||||||
|
MODULE_AUTHOR("Nikita Yushchenko <nikita.yoush@cogentembedded.com>");
|
||||||
|
MODULE_AUTHOR("Andrey Smirnov <andrew.smirnov@gmail.com>");
|
||||||
|
MODULE_DESCRIPTION("RAVE SP core driver");
|
|
@ -1,13 +1,9 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
/*
|
/*
|
||||||
* STM32 Low-Power Timer parent driver.
|
* STM32 Low-Power Timer parent driver.
|
||||||
*
|
|
||||||
* Copyright (C) STMicroelectronics 2017
|
* Copyright (C) STMicroelectronics 2017
|
||||||
*
|
|
||||||
* Author: Fabrice Gasnier <fabrice.gasnier@st.com>
|
* Author: Fabrice Gasnier <fabrice.gasnier@st.com>
|
||||||
*
|
|
||||||
* Inspired by Benjamin Gaignard's stm32-timers driver
|
* Inspired by Benjamin Gaignard's stm32-timers driver
|
||||||
*
|
|
||||||
* License terms: GNU General Public License (GPL), version 2
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/mfd/stm32-lptimer.h>
|
#include <linux/mfd/stm32-lptimer.h>
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
/*
|
/*
|
||||||
* Copyright (C) STMicroelectronics 2016
|
* Copyright (C) STMicroelectronics 2016
|
||||||
*
|
|
||||||
* Author: Benjamin Gaignard <benjamin.gaignard@st.com>
|
* Author: Benjamin Gaignard <benjamin.gaignard@st.com>
|
||||||
*
|
|
||||||
* License terms: GNU General Public License (GPL), version 2
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/mfd/stm32-timers.h>
|
#include <linux/mfd/stm32-timers.h>
|
||||||
|
|
|
@ -124,7 +124,7 @@ static int ti_tscadc_probe(struct platform_device *pdev)
|
||||||
struct ti_tscadc_dev *tscadc;
|
struct ti_tscadc_dev *tscadc;
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
struct clk *clk;
|
struct clk *clk;
|
||||||
struct device_node *node = pdev->dev.of_node;
|
struct device_node *node;
|
||||||
struct mfd_cell *cell;
|
struct mfd_cell *cell;
|
||||||
struct property *prop;
|
struct property *prop;
|
||||||
const __be32 *cur;
|
const __be32 *cur;
|
||||||
|
|
|
@ -9,6 +9,26 @@
|
||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
#include <linux/mfd/tmio.h>
|
#include <linux/mfd/tmio.h>
|
||||||
|
|
||||||
|
#define CNF_CMD 0x04
|
||||||
|
#define CNF_CTL_BASE 0x10
|
||||||
|
#define CNF_INT_PIN 0x3d
|
||||||
|
#define CNF_STOP_CLK_CTL 0x40
|
||||||
|
#define CNF_GCLK_CTL 0x41
|
||||||
|
#define CNF_SD_CLK_MODE 0x42
|
||||||
|
#define CNF_PIN_STATUS 0x44
|
||||||
|
#define CNF_PWR_CTL_1 0x48
|
||||||
|
#define CNF_PWR_CTL_2 0x49
|
||||||
|
#define CNF_PWR_CTL_3 0x4a
|
||||||
|
#define CNF_CARD_DETECT_MODE 0x4c
|
||||||
|
#define CNF_SD_SLOT 0x50
|
||||||
|
#define CNF_EXT_GCLK_CTL_1 0xf0
|
||||||
|
#define CNF_EXT_GCLK_CTL_2 0xf1
|
||||||
|
#define CNF_EXT_GCLK_CTL_3 0xf9
|
||||||
|
#define CNF_SD_LED_EN_1 0xfa
|
||||||
|
#define CNF_SD_LED_EN_2 0xfe
|
||||||
|
|
||||||
|
#define SDCREN 0x2 /* Enable access to MMC CTL regs. (flag in COMMAND_REG)*/
|
||||||
|
|
||||||
int tmio_core_mmc_enable(void __iomem *cnf, int shift, unsigned long base)
|
int tmio_core_mmc_enable(void __iomem *cnf, int shift, unsigned long base)
|
||||||
{
|
{
|
||||||
/* Enable the MMC/SD Control registers */
|
/* Enable the MMC/SD Control registers */
|
||||||
|
|
|
@ -496,6 +496,10 @@ config PCI_ENDPOINT_TEST
|
||||||
Enable this configuration option to enable the host side test driver
|
Enable this configuration option to enable the host side test driver
|
||||||
for PCI Endpoint.
|
for PCI Endpoint.
|
||||||
|
|
||||||
|
config MISC_RTSX
|
||||||
|
tristate
|
||||||
|
default MISC_RTSX_PCI || MISC_RTSX_USB
|
||||||
|
|
||||||
source "drivers/misc/c2port/Kconfig"
|
source "drivers/misc/c2port/Kconfig"
|
||||||
source "drivers/misc/eeprom/Kconfig"
|
source "drivers/misc/eeprom/Kconfig"
|
||||||
source "drivers/misc/cb710/Kconfig"
|
source "drivers/misc/cb710/Kconfig"
|
||||||
|
@ -508,4 +512,5 @@ source "drivers/misc/mic/Kconfig"
|
||||||
source "drivers/misc/genwqe/Kconfig"
|
source "drivers/misc/genwqe/Kconfig"
|
||||||
source "drivers/misc/echo/Kconfig"
|
source "drivers/misc/echo/Kconfig"
|
||||||
source "drivers/misc/cxl/Kconfig"
|
source "drivers/misc/cxl/Kconfig"
|
||||||
|
source "drivers/misc/cardreader/Kconfig"
|
||||||
endmenu
|
endmenu
|
||||||
|
|
|
@ -55,6 +55,7 @@ obj-$(CONFIG_CXL_BASE) += cxl/
|
||||||
obj-$(CONFIG_ASPEED_LPC_CTRL) += aspeed-lpc-ctrl.o
|
obj-$(CONFIG_ASPEED_LPC_CTRL) += aspeed-lpc-ctrl.o
|
||||||
obj-$(CONFIG_ASPEED_LPC_SNOOP) += aspeed-lpc-snoop.o
|
obj-$(CONFIG_ASPEED_LPC_SNOOP) += aspeed-lpc-snoop.o
|
||||||
obj-$(CONFIG_PCI_ENDPOINT_TEST) += pci_endpoint_test.o
|
obj-$(CONFIG_PCI_ENDPOINT_TEST) += pci_endpoint_test.o
|
||||||
|
obj-$(CONFIG_MISC_RTSX) += cardreader/
|
||||||
|
|
||||||
lkdtm-$(CONFIG_LKDTM) += lkdtm_core.o
|
lkdtm-$(CONFIG_LKDTM) += lkdtm_core.o
|
||||||
lkdtm-$(CONFIG_LKDTM) += lkdtm_bugs.o
|
lkdtm-$(CONFIG_LKDTM) += lkdtm_bugs.o
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
config MISC_RTSX_PCI
|
||||||
|
tristate "Realtek PCI-E card reader"
|
||||||
|
depends on PCI
|
||||||
|
select MFD_CORE
|
||||||
|
help
|
||||||
|
This supports for Realtek PCI-Express card reader including rts5209,
|
||||||
|
rts5227, rts522A, rts5229, rts5249, rts524A, rts525A, rtl8411, rts5260.
|
||||||
|
Realtek card readers support access to many types of memory cards,
|
||||||
|
such as Memory Stick, Memory Stick Pro, Secure Digital and
|
||||||
|
MultiMediaCard.
|
||||||
|
|
||||||
|
config MISC_RTSX_USB
|
||||||
|
tristate "Realtek USB card reader"
|
||||||
|
depends on USB
|
||||||
|
select MFD_CORE
|
||||||
|
help
|
||||||
|
Select this option to get support for Realtek USB 2.0 card readers
|
||||||
|
including RTS5129, RTS5139, RTS5179 and RTS5170.
|
||||||
|
Realtek card reader supports access to many types of memory cards,
|
||||||
|
such as Memory Stick Pro, Secure Digital and MultiMediaCard.
|
|
@ -0,0 +1,4 @@
|
||||||
|
rtsx_pci-objs := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o rts5227.o rts5249.o rts5260.o
|
||||||
|
|
||||||
|
obj-$(CONFIG_MISC_RTSX_PCI) += rtsx_pci.o
|
||||||
|
obj-$(CONFIG_MISC_RTSX_USB) += rtsx_usb.o
|
|
@ -23,7 +23,7 @@
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/bitops.h>
|
#include <linux/bitops.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/mfd/rtsx_pci.h>
|
#include <linux/rtsx_pci.h>
|
||||||
|
|
||||||
#include "rtsx_pcr.h"
|
#include "rtsx_pcr.h"
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/mfd/rtsx_pci.h>
|
#include <linux/rtsx_pci.h>
|
||||||
|
|
||||||
#include "rtsx_pcr.h"
|
#include "rtsx_pcr.h"
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/mfd/rtsx_pci.h>
|
#include <linux/rtsx_pci.h>
|
||||||
|
|
||||||
#include "rtsx_pcr.h"
|
#include "rtsx_pcr.h"
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/mfd/rtsx_pci.h>
|
#include <linux/rtsx_pci.h>
|
||||||
|
|
||||||
#include "rtsx_pcr.h"
|
#include "rtsx_pcr.h"
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/mfd/rtsx_pci.h>
|
#include <linux/rtsx_pci.h>
|
||||||
|
|
||||||
#include "rtsx_pcr.h"
|
#include "rtsx_pcr.h"
|
||||||
|
|
||||||
|
@ -738,4 +738,3 @@ void rts525a_init_params(struct rtsx_pcr *pcr)
|
||||||
pcr->reg_pm_ctrl3 = RTS524A_PM_CTRL3;
|
pcr->reg_pm_ctrl3 = RTS524A_PM_CTRL3;
|
||||||
pcr->ops = &rts525a_pcr_ops;
|
pcr->ops = &rts525a_pcr_ops;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,748 @@
|
||||||
|
/* Driver for Realtek PCI-Express card reader
|
||||||
|
*
|
||||||
|
* Copyright(c) 2016-2017 Realtek Semiconductor Corp. All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2, or (at your option) any
|
||||||
|
* later version.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* Author:
|
||||||
|
* Steven FENG <steven_feng@realsil.com.cn>
|
||||||
|
* Rui FENG <rui_feng@realsil.com.cn>
|
||||||
|
* Wei WANG <wei_wang@realsil.com.cn>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
|
#include <linux/rtsx_pci.h>
|
||||||
|
|
||||||
|
#include "rts5260.h"
|
||||||
|
#include "rtsx_pcr.h"
|
||||||
|
|
||||||
|
static u8 rts5260_get_ic_version(struct rtsx_pcr *pcr)
|
||||||
|
{
|
||||||
|
u8 val;
|
||||||
|
|
||||||
|
rtsx_pci_read_register(pcr, DUMMY_REG_RESET_0, &val);
|
||||||
|
return val & IC_VERSION_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rts5260_fill_driving(struct rtsx_pcr *pcr, u8 voltage)
|
||||||
|
{
|
||||||
|
u8 driving_3v3[6][3] = {
|
||||||
|
{0x94, 0x94, 0x94},
|
||||||
|
{0x11, 0x11, 0x18},
|
||||||
|
{0x55, 0x55, 0x5C},
|
||||||
|
{0x94, 0x94, 0x94},
|
||||||
|
{0x94, 0x94, 0x94},
|
||||||
|
{0xFF, 0xFF, 0xFF},
|
||||||
|
};
|
||||||
|
u8 driving_1v8[6][3] = {
|
||||||
|
{0x9A, 0x89, 0x89},
|
||||||
|
{0xC4, 0xC4, 0xC4},
|
||||||
|
{0x3C, 0x3C, 0x3C},
|
||||||
|
{0x9B, 0x99, 0x99},
|
||||||
|
{0x9A, 0x89, 0x89},
|
||||||
|
{0xFE, 0xFE, 0xFE},
|
||||||
|
};
|
||||||
|
u8 (*driving)[3], drive_sel;
|
||||||
|
|
||||||
|
if (voltage == OUTPUT_3V3) {
|
||||||
|
driving = driving_3v3;
|
||||||
|
drive_sel = pcr->sd30_drive_sel_3v3;
|
||||||
|
} else {
|
||||||
|
driving = driving_1v8;
|
||||||
|
drive_sel = pcr->sd30_drive_sel_1v8;
|
||||||
|
}
|
||||||
|
|
||||||
|
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CLK_DRIVE_SEL,
|
||||||
|
0xFF, driving[drive_sel][0]);
|
||||||
|
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_CMD_DRIVE_SEL,
|
||||||
|
0xFF, driving[drive_sel][1]);
|
||||||
|
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DAT_DRIVE_SEL,
|
||||||
|
0xFF, driving[drive_sel][2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rtsx_base_fetch_vendor_settings(struct rtsx_pcr *pcr)
|
||||||
|
{
|
||||||
|
u32 reg;
|
||||||
|
|
||||||
|
rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, ®);
|
||||||
|
pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
|
||||||
|
|
||||||
|
if (!rtsx_vendor_setting_valid(reg)) {
|
||||||
|
pcr_dbg(pcr, "skip fetch vendor setting\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pcr->aspm_en = rtsx_reg_to_aspm(reg);
|
||||||
|
pcr->sd30_drive_sel_1v8 = rtsx_reg_to_sd30_drive_sel_1v8(reg);
|
||||||
|
pcr->card_drive_sel &= 0x3F;
|
||||||
|
pcr->card_drive_sel |= rtsx_reg_to_card_drive_sel(reg);
|
||||||
|
|
||||||
|
rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG2, ®);
|
||||||
|
pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);
|
||||||
|
pcr->sd30_drive_sel_3v3 = rtsx_reg_to_sd30_drive_sel_3v3(reg);
|
||||||
|
if (rtsx_reg_check_reverse_socket(reg))
|
||||||
|
pcr->flags |= PCR_REVERSE_SOCKET;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rtsx_base_force_power_down(struct rtsx_pcr *pcr, u8 pm_state)
|
||||||
|
{
|
||||||
|
/* Set relink_time to 0 */
|
||||||
|
rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 1, MASK_8_BIT_DEF, 0);
|
||||||
|
rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 2, MASK_8_BIT_DEF, 0);
|
||||||
|
rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 3,
|
||||||
|
RELINK_TIME_MASK, 0);
|
||||||
|
|
||||||
|
if (pm_state == HOST_ENTER_S3)
|
||||||
|
rtsx_pci_write_register(pcr, pcr->reg_pm_ctrl3,
|
||||||
|
D3_DELINK_MODE_EN, D3_DELINK_MODE_EN);
|
||||||
|
|
||||||
|
rtsx_pci_write_register(pcr, FPDCTL, ALL_POWER_DOWN, ALL_POWER_DOWN);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rtsx_base_enable_auto_blink(struct rtsx_pcr *pcr)
|
||||||
|
{
|
||||||
|
return rtsx_pci_write_register(pcr, OLT_LED_CTL,
|
||||||
|
LED_SHINE_MASK, LED_SHINE_EN);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rtsx_base_disable_auto_blink(struct rtsx_pcr *pcr)
|
||||||
|
{
|
||||||
|
return rtsx_pci_write_register(pcr, OLT_LED_CTL,
|
||||||
|
LED_SHINE_MASK, LED_SHINE_DISABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rts5260_turn_on_led(struct rtsx_pcr *pcr)
|
||||||
|
{
|
||||||
|
return rtsx_pci_write_register(pcr, RTS5260_REG_GPIO_CTL0,
|
||||||
|
RTS5260_REG_GPIO_MASK, RTS5260_REG_GPIO_ON);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rts5260_turn_off_led(struct rtsx_pcr *pcr)
|
||||||
|
{
|
||||||
|
return rtsx_pci_write_register(pcr, RTS5260_REG_GPIO_CTL0,
|
||||||
|
RTS5260_REG_GPIO_MASK, RTS5260_REG_GPIO_OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SD Pull Control Enable:
|
||||||
|
* SD_DAT[3:0] ==> pull up
|
||||||
|
* SD_CD ==> pull up
|
||||||
|
* SD_WP ==> pull up
|
||||||
|
* SD_CMD ==> pull up
|
||||||
|
* SD_CLK ==> pull down
|
||||||
|
*/
|
||||||
|
static const u32 rts5260_sd_pull_ctl_enable_tbl[] = {
|
||||||
|
RTSX_REG_PAIR(CARD_PULL_CTL1, 0x66),
|
||||||
|
RTSX_REG_PAIR(CARD_PULL_CTL2, 0xAA),
|
||||||
|
RTSX_REG_PAIR(CARD_PULL_CTL3, 0xE9),
|
||||||
|
RTSX_REG_PAIR(CARD_PULL_CTL4, 0xAA),
|
||||||
|
0,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* SD Pull Control Disable:
|
||||||
|
* SD_DAT[3:0] ==> pull down
|
||||||
|
* SD_CD ==> pull up
|
||||||
|
* SD_WP ==> pull down
|
||||||
|
* SD_CMD ==> pull down
|
||||||
|
* SD_CLK ==> pull down
|
||||||
|
*/
|
||||||
|
static const u32 rts5260_sd_pull_ctl_disable_tbl[] = {
|
||||||
|
RTSX_REG_PAIR(CARD_PULL_CTL1, 0x66),
|
||||||
|
RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
|
||||||
|
RTSX_REG_PAIR(CARD_PULL_CTL3, 0xD5),
|
||||||
|
RTSX_REG_PAIR(CARD_PULL_CTL4, 0x55),
|
||||||
|
0,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* MS Pull Control Enable:
|
||||||
|
* MS CD ==> pull up
|
||||||
|
* others ==> pull down
|
||||||
|
*/
|
||||||
|
static const u32 rts5260_ms_pull_ctl_enable_tbl[] = {
|
||||||
|
RTSX_REG_PAIR(CARD_PULL_CTL4, 0x55),
|
||||||
|
RTSX_REG_PAIR(CARD_PULL_CTL5, 0x55),
|
||||||
|
RTSX_REG_PAIR(CARD_PULL_CTL6, 0x15),
|
||||||
|
0,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* MS Pull Control Disable:
|
||||||
|
* MS CD ==> pull up
|
||||||
|
* others ==> pull down
|
||||||
|
*/
|
||||||
|
static const u32 rts5260_ms_pull_ctl_disable_tbl[] = {
|
||||||
|
RTSX_REG_PAIR(CARD_PULL_CTL4, 0x55),
|
||||||
|
RTSX_REG_PAIR(CARD_PULL_CTL5, 0x55),
|
||||||
|
RTSX_REG_PAIR(CARD_PULL_CTL6, 0x15),
|
||||||
|
0,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int sd_set_sample_push_timing_sd30(struct rtsx_pcr *pcr)
|
||||||
|
{
|
||||||
|
rtsx_pci_write_register(pcr, SD_CFG1, SD_MODE_SELECT_MASK
|
||||||
|
| SD_ASYNC_FIFO_NOT_RST, SD_30_MODE | SD_ASYNC_FIFO_NOT_RST);
|
||||||
|
rtsx_pci_write_register(pcr, CLK_CTL, CLK_LOW_FREQ, CLK_LOW_FREQ);
|
||||||
|
rtsx_pci_write_register(pcr, CARD_CLK_SOURCE, 0xFF,
|
||||||
|
CRC_VAR_CLK0 | SD30_FIX_CLK | SAMPLE_VAR_CLK1);
|
||||||
|
rtsx_pci_write_register(pcr, CLK_CTL, CLK_LOW_FREQ, 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rts5260_card_power_on(struct rtsx_pcr *pcr, int card)
|
||||||
|
{
|
||||||
|
int err = 0;
|
||||||
|
struct rtsx_cr_option *option = &pcr->option;
|
||||||
|
|
||||||
|
if (option->ocp_en)
|
||||||
|
rtsx_pci_enable_ocp(pcr);
|
||||||
|
|
||||||
|
rtsx_pci_init_cmd(pcr);
|
||||||
|
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_CONFIG2,
|
||||||
|
DV331812_VDD1, DV331812_VDD1);
|
||||||
|
err = rtsx_pci_send_cmd(pcr, CMD_TIMEOUT_DEF);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
rtsx_pci_init_cmd(pcr);
|
||||||
|
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_VCC_CFG0,
|
||||||
|
RTS5260_DVCC_TUNE_MASK, RTS5260_DVCC_33);
|
||||||
|
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_VCC_CFG1,
|
||||||
|
LDO_POW_SDVDD1_MASK, LDO_POW_SDVDD1_ON);
|
||||||
|
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_CONFIG2,
|
||||||
|
DV331812_POWERON, DV331812_POWERON);
|
||||||
|
err = rtsx_pci_send_cmd(pcr, CMD_TIMEOUT_DEF);
|
||||||
|
|
||||||
|
msleep(20);
|
||||||
|
|
||||||
|
if (pcr->extra_caps & EXTRA_CAPS_SD_SDR50 ||
|
||||||
|
pcr->extra_caps & EXTRA_CAPS_SD_SDR104)
|
||||||
|
sd_set_sample_push_timing_sd30(pcr);
|
||||||
|
|
||||||
|
/* Initialize SD_CFG1 register */
|
||||||
|
rtsx_pci_write_register(pcr, SD_CFG1, 0xFF,
|
||||||
|
SD_CLK_DIVIDE_128 | SD_20_MODE);
|
||||||
|
|
||||||
|
rtsx_pci_write_register(pcr, SD_SAMPLE_POINT_CTL,
|
||||||
|
0xFF, SD20_RX_POS_EDGE);
|
||||||
|
rtsx_pci_write_register(pcr, SD_PUSH_POINT_CTL, 0xFF, 0);
|
||||||
|
rtsx_pci_write_register(pcr, CARD_STOP, SD_STOP | SD_CLR_ERR,
|
||||||
|
SD_STOP | SD_CLR_ERR);
|
||||||
|
|
||||||
|
/* Reset SD_CFG3 register */
|
||||||
|
rtsx_pci_write_register(pcr, SD_CFG3, SD30_CLK_END_EN, 0);
|
||||||
|
rtsx_pci_write_register(pcr, REG_SD_STOP_SDCLK_CFG,
|
||||||
|
SD30_CLK_STOP_CFG_EN | SD30_CLK_STOP_CFG1 |
|
||||||
|
SD30_CLK_STOP_CFG0, 0);
|
||||||
|
|
||||||
|
rtsx_pci_write_register(pcr, REG_PRE_RW_MODE, EN_INFINITE_MODE, 0);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rts5260_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
|
||||||
|
{
|
||||||
|
switch (voltage) {
|
||||||
|
case OUTPUT_3V3:
|
||||||
|
rtsx_pci_write_register(pcr, LDO_CONFIG2,
|
||||||
|
DV331812_VDD1, DV331812_VDD1);
|
||||||
|
rtsx_pci_write_register(pcr, LDO_DV18_CFG,
|
||||||
|
DV331812_MASK, DV331812_33);
|
||||||
|
rtsx_pci_write_register(pcr, SD_PAD_CTL, SD_IO_USING_1V8, 0);
|
||||||
|
break;
|
||||||
|
case OUTPUT_1V8:
|
||||||
|
rtsx_pci_write_register(pcr, LDO_CONFIG2,
|
||||||
|
DV331812_VDD1, DV331812_VDD1);
|
||||||
|
rtsx_pci_write_register(pcr, LDO_DV18_CFG,
|
||||||
|
DV331812_MASK, DV331812_17);
|
||||||
|
rtsx_pci_write_register(pcr, SD_PAD_CTL, SD_IO_USING_1V8,
|
||||||
|
SD_IO_USING_1V8);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set pad drive */
|
||||||
|
rtsx_pci_init_cmd(pcr);
|
||||||
|
rts5260_fill_driving(pcr, voltage);
|
||||||
|
return rtsx_pci_send_cmd(pcr, CMD_TIMEOUT_DEF);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rts5260_stop_cmd(struct rtsx_pcr *pcr)
|
||||||
|
{
|
||||||
|
rtsx_pci_writel(pcr, RTSX_HCBCTLR, STOP_CMD);
|
||||||
|
rtsx_pci_writel(pcr, RTSX_HDBCTLR, STOP_DMA);
|
||||||
|
rtsx_pci_write_register(pcr, RTS5260_DMA_RST_CTL_0,
|
||||||
|
RTS5260_DMA_RST | RTS5260_ADMA3_RST,
|
||||||
|
RTS5260_DMA_RST | RTS5260_ADMA3_RST);
|
||||||
|
rtsx_pci_write_register(pcr, RBCTL, RB_FLUSH, RB_FLUSH);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rts5260_card_before_power_off(struct rtsx_pcr *pcr)
|
||||||
|
{
|
||||||
|
struct rtsx_cr_option *option = &pcr->option;
|
||||||
|
|
||||||
|
rts5260_stop_cmd(pcr);
|
||||||
|
rts5260_switch_output_voltage(pcr, OUTPUT_3V3);
|
||||||
|
|
||||||
|
if (option->ocp_en)
|
||||||
|
rtsx_pci_disable_ocp(pcr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rts5260_card_power_off(struct rtsx_pcr *pcr, int card)
|
||||||
|
{
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
rts5260_card_before_power_off(pcr);
|
||||||
|
|
||||||
|
rtsx_pci_init_cmd(pcr);
|
||||||
|
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_VCC_CFG1,
|
||||||
|
LDO_POW_SDVDD1_MASK, LDO_POW_SDVDD1_OFF);
|
||||||
|
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_CONFIG2,
|
||||||
|
DV331812_POWERON, DV331812_POWEROFF);
|
||||||
|
err = rtsx_pci_send_cmd(pcr, CMD_TIMEOUT_DEF);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rts5260_init_ocp(struct rtsx_pcr *pcr)
|
||||||
|
{
|
||||||
|
struct rtsx_cr_option *option = &pcr->option;
|
||||||
|
|
||||||
|
if (option->ocp_en) {
|
||||||
|
u8 mask, val;
|
||||||
|
|
||||||
|
rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL,
|
||||||
|
RTS5260_DVCC_OCP_EN |
|
||||||
|
RTS5260_DVCC_OCP_CL_EN,
|
||||||
|
RTS5260_DVCC_OCP_EN |
|
||||||
|
RTS5260_DVCC_OCP_CL_EN);
|
||||||
|
rtsx_pci_write_register(pcr, RTS5260_DVIO_CTRL,
|
||||||
|
RTS5260_DVIO_OCP_EN |
|
||||||
|
RTS5260_DVIO_OCP_CL_EN,
|
||||||
|
RTS5260_DVIO_OCP_EN |
|
||||||
|
RTS5260_DVIO_OCP_CL_EN);
|
||||||
|
|
||||||
|
rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL,
|
||||||
|
RTS5260_DVCC_OCP_THD_MASK,
|
||||||
|
option->sd_400mA_ocp_thd);
|
||||||
|
|
||||||
|
rtsx_pci_write_register(pcr, RTS5260_DVIO_CTRL,
|
||||||
|
RTS5260_DVIO_OCP_THD_MASK,
|
||||||
|
RTS5260_DVIO_OCP_THD_350);
|
||||||
|
|
||||||
|
rtsx_pci_write_register(pcr, RTS5260_DV331812_CFG,
|
||||||
|
RTS5260_DV331812_OCP_THD_MASK,
|
||||||
|
RTS5260_DV331812_OCP_THD_210);
|
||||||
|
|
||||||
|
mask = SD_OCP_GLITCH_MASK | SDVIO_OCP_GLITCH_MASK;
|
||||||
|
val = pcr->hw_param.ocp_glitch;
|
||||||
|
rtsx_pci_write_register(pcr, REG_OCPGLITCH, mask, val);
|
||||||
|
|
||||||
|
rtsx_pci_enable_ocp(pcr);
|
||||||
|
} else {
|
||||||
|
rtsx_pci_write_register(pcr, RTS5260_DVCC_CTRL,
|
||||||
|
RTS5260_DVCC_OCP_EN |
|
||||||
|
RTS5260_DVCC_OCP_CL_EN, 0);
|
||||||
|
rtsx_pci_write_register(pcr, RTS5260_DVIO_CTRL,
|
||||||
|
RTS5260_DVIO_OCP_EN |
|
||||||
|
RTS5260_DVIO_OCP_CL_EN, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rts5260_enable_ocp(struct rtsx_pcr *pcr)
|
||||||
|
{
|
||||||
|
u8 val = 0;
|
||||||
|
|
||||||
|
rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN, 0);
|
||||||
|
|
||||||
|
val = SD_OCP_INT_EN | SD_DETECT_EN;
|
||||||
|
val |= SDVIO_OCP_INT_EN | SDVIO_DETECT_EN;
|
||||||
|
rtsx_pci_write_register(pcr, REG_OCPCTL, 0xFF, val);
|
||||||
|
rtsx_pci_write_register(pcr, REG_DV3318_OCPCTL,
|
||||||
|
DV3318_DETECT_EN | DV3318_OCP_INT_EN,
|
||||||
|
DV3318_DETECT_EN | DV3318_OCP_INT_EN);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rts5260_disable_ocp(struct rtsx_pcr *pcr)
|
||||||
|
{
|
||||||
|
u8 mask = 0;
|
||||||
|
|
||||||
|
mask = SD_OCP_INT_EN | SD_DETECT_EN;
|
||||||
|
mask |= SDVIO_OCP_INT_EN | SDVIO_DETECT_EN;
|
||||||
|
rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0);
|
||||||
|
rtsx_pci_write_register(pcr, REG_DV3318_OCPCTL,
|
||||||
|
DV3318_DETECT_EN | DV3318_OCP_INT_EN, 0);
|
||||||
|
|
||||||
|
rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN,
|
||||||
|
OC_POWER_DOWN);
|
||||||
|
}
|
||||||
|
|
||||||
|
int rts5260_get_ocpstat(struct rtsx_pcr *pcr, u8 *val)
|
||||||
|
{
|
||||||
|
return rtsx_pci_read_register(pcr, REG_OCPSTAT, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
int rts5260_get_ocpstat2(struct rtsx_pcr *pcr, u8 *val)
|
||||||
|
{
|
||||||
|
return rtsx_pci_read_register(pcr, REG_DV3318_OCPSTAT, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rts5260_clear_ocpstat(struct rtsx_pcr *pcr)
|
||||||
|
{
|
||||||
|
u8 mask = 0;
|
||||||
|
u8 val = 0;
|
||||||
|
|
||||||
|
mask = SD_OCP_INT_CLR | SD_OC_CLR;
|
||||||
|
mask |= SDVIO_OCP_INT_CLR | SDVIO_OC_CLR;
|
||||||
|
val = SD_OCP_INT_CLR | SD_OC_CLR;
|
||||||
|
val |= SDVIO_OCP_INT_CLR | SDVIO_OC_CLR;
|
||||||
|
|
||||||
|
rtsx_pci_write_register(pcr, REG_OCPCTL, mask, val);
|
||||||
|
rtsx_pci_write_register(pcr, REG_DV3318_OCPCTL,
|
||||||
|
DV3318_OCP_INT_CLR | DV3318_OCP_CLR,
|
||||||
|
DV3318_OCP_INT_CLR | DV3318_OCP_CLR);
|
||||||
|
udelay(10);
|
||||||
|
rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0);
|
||||||
|
rtsx_pci_write_register(pcr, REG_DV3318_OCPCTL,
|
||||||
|
DV3318_OCP_INT_CLR | DV3318_OCP_CLR, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rts5260_process_ocp(struct rtsx_pcr *pcr)
|
||||||
|
{
|
||||||
|
if (!pcr->option.ocp_en)
|
||||||
|
return;
|
||||||
|
|
||||||
|
rtsx_pci_get_ocpstat(pcr, &pcr->ocp_stat);
|
||||||
|
rts5260_get_ocpstat2(pcr, &pcr->ocp_stat2);
|
||||||
|
if (pcr->card_exist & SD_EXIST)
|
||||||
|
rtsx_sd_power_off_card3v3(pcr);
|
||||||
|
else if (pcr->card_exist & MS_EXIST)
|
||||||
|
rtsx_ms_power_off_card3v3(pcr);
|
||||||
|
|
||||||
|
if (!(pcr->card_exist & MS_EXIST) && !(pcr->card_exist & SD_EXIST)) {
|
||||||
|
if ((pcr->ocp_stat & (SD_OC_NOW | SD_OC_EVER |
|
||||||
|
SDVIO_OC_NOW | SDVIO_OC_EVER)) ||
|
||||||
|
(pcr->ocp_stat2 & (DV3318_OCP_NOW | DV3318_OCP_EVER)))
|
||||||
|
rtsx_pci_clear_ocpstat(pcr);
|
||||||
|
pcr->ocp_stat = 0;
|
||||||
|
pcr->ocp_stat2 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((pcr->ocp_stat & (SD_OC_NOW | SD_OC_EVER |
|
||||||
|
SDVIO_OC_NOW | SDVIO_OC_EVER)) ||
|
||||||
|
(pcr->ocp_stat2 & (DV3318_OCP_NOW | DV3318_OCP_EVER))) {
|
||||||
|
if (pcr->card_exist & SD_EXIST)
|
||||||
|
rtsx_pci_write_register(pcr, CARD_OE, SD_OUTPUT_EN, 0);
|
||||||
|
else if (pcr->card_exist & MS_EXIST)
|
||||||
|
rtsx_pci_write_register(pcr, CARD_OE, MS_OUTPUT_EN, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int rts5260_init_hw(struct rtsx_pcr *pcr)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
rtsx_pci_init_ocp(pcr);
|
||||||
|
|
||||||
|
rtsx_pci_init_cmd(pcr);
|
||||||
|
|
||||||
|
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, L1SUB_CONFIG1,
|
||||||
|
AUX_CLK_ACTIVE_SEL_MASK, MAC_CKSW_DONE);
|
||||||
|
/* Rest L1SUB Config */
|
||||||
|
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, L1SUB_CONFIG3, 0xFF, 0x00);
|
||||||
|
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PM_CLK_FORCE_CTL,
|
||||||
|
CLK_PM_EN, CLK_PM_EN);
|
||||||
|
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWD_SUSPEND_EN, 0xFF, 0xFF);
|
||||||
|
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL,
|
||||||
|
PWR_GATE_EN, PWR_GATE_EN);
|
||||||
|
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, REG_VREF,
|
||||||
|
PWD_SUSPND_EN, PWD_SUSPND_EN);
|
||||||
|
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, RBCTL,
|
||||||
|
U_AUTO_DMA_EN_MASK, U_AUTO_DMA_DISABLE);
|
||||||
|
|
||||||
|
if (pcr->flags & PCR_REVERSE_SOCKET)
|
||||||
|
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB0, 0xB0);
|
||||||
|
else
|
||||||
|
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB0, 0x80);
|
||||||
|
|
||||||
|
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OBFF_CFG,
|
||||||
|
OBFF_EN_MASK, OBFF_DISABLE);
|
||||||
|
|
||||||
|
err = rtsx_pci_send_cmd(pcr, CMD_TIMEOUT_DEF);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rts5260_pwr_saving_setting(struct rtsx_pcr *pcr)
|
||||||
|
{
|
||||||
|
int lss_l1_1, lss_l1_2;
|
||||||
|
|
||||||
|
lss_l1_1 = rtsx_check_dev_flag(pcr, ASPM_L1_1_EN)
|
||||||
|
| rtsx_check_dev_flag(pcr, PM_L1_1_EN);
|
||||||
|
lss_l1_2 = rtsx_check_dev_flag(pcr, ASPM_L1_2_EN)
|
||||||
|
| rtsx_check_dev_flag(pcr, PM_L1_2_EN);
|
||||||
|
|
||||||
|
if (lss_l1_2) {
|
||||||
|
pcr_dbg(pcr, "Set parameters for L1.2.");
|
||||||
|
rtsx_pci_write_register(pcr, PWR_GLOBAL_CTRL,
|
||||||
|
0xFF, PCIE_L1_2_EN);
|
||||||
|
rtsx_pci_write_register(pcr, PWR_FE_CTL,
|
||||||
|
0xFF, PCIE_L1_2_PD_FE_EN);
|
||||||
|
} else if (lss_l1_1) {
|
||||||
|
pcr_dbg(pcr, "Set parameters for L1.1.");
|
||||||
|
rtsx_pci_write_register(pcr, PWR_GLOBAL_CTRL,
|
||||||
|
0xFF, PCIE_L1_1_EN);
|
||||||
|
rtsx_pci_write_register(pcr, PWR_FE_CTL,
|
||||||
|
0xFF, PCIE_L1_1_PD_FE_EN);
|
||||||
|
} else {
|
||||||
|
pcr_dbg(pcr, "Set parameters for L1.");
|
||||||
|
rtsx_pci_write_register(pcr, PWR_GLOBAL_CTRL,
|
||||||
|
0xFF, PCIE_L1_0_EN);
|
||||||
|
rtsx_pci_write_register(pcr, PWR_FE_CTL,
|
||||||
|
0xFF, PCIE_L1_0_PD_FE_EN);
|
||||||
|
}
|
||||||
|
|
||||||
|
rtsx_pci_write_register(pcr, CFG_L1_0_PCIE_DPHY_RET_VALUE,
|
||||||
|
0xFF, CFG_L1_0_RET_VALUE_DEFAULT);
|
||||||
|
rtsx_pci_write_register(pcr, CFG_L1_0_PCIE_MAC_RET_VALUE,
|
||||||
|
0xFF, CFG_L1_0_RET_VALUE_DEFAULT);
|
||||||
|
rtsx_pci_write_register(pcr, CFG_L1_0_CRC_SD30_RET_VALUE,
|
||||||
|
0xFF, CFG_L1_0_RET_VALUE_DEFAULT);
|
||||||
|
rtsx_pci_write_register(pcr, CFG_L1_0_CRC_SD40_RET_VALUE,
|
||||||
|
0xFF, CFG_L1_0_RET_VALUE_DEFAULT);
|
||||||
|
rtsx_pci_write_register(pcr, CFG_L1_0_SYS_RET_VALUE,
|
||||||
|
0xFF, CFG_L1_0_RET_VALUE_DEFAULT);
|
||||||
|
/*Option cut APHY*/
|
||||||
|
rtsx_pci_write_register(pcr, CFG_PCIE_APHY_OFF_0,
|
||||||
|
0xFF, CFG_PCIE_APHY_OFF_0_DEFAULT);
|
||||||
|
rtsx_pci_write_register(pcr, CFG_PCIE_APHY_OFF_1,
|
||||||
|
0xFF, CFG_PCIE_APHY_OFF_1_DEFAULT);
|
||||||
|
rtsx_pci_write_register(pcr, CFG_PCIE_APHY_OFF_2,
|
||||||
|
0xFF, CFG_PCIE_APHY_OFF_2_DEFAULT);
|
||||||
|
rtsx_pci_write_register(pcr, CFG_PCIE_APHY_OFF_3,
|
||||||
|
0xFF, CFG_PCIE_APHY_OFF_3_DEFAULT);
|
||||||
|
/*CDR DEC*/
|
||||||
|
rtsx_pci_write_register(pcr, PWC_CDR, 0xFF, PWC_CDR_DEFAULT);
|
||||||
|
/*PWMPFM*/
|
||||||
|
rtsx_pci_write_register(pcr, CFG_LP_FPWM_VALUE,
|
||||||
|
0xFF, CFG_LP_FPWM_VALUE_DEFAULT);
|
||||||
|
/*No Power Saving WA*/
|
||||||
|
rtsx_pci_write_register(pcr, CFG_L1_0_CRC_MISC_RET_VALUE,
|
||||||
|
0xFF, CFG_L1_0_CRC_MISC_RET_VALUE_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rts5260_init_from_cfg(struct rtsx_pcr *pcr)
|
||||||
|
{
|
||||||
|
struct rtsx_cr_option *option = &pcr->option;
|
||||||
|
u32 lval;
|
||||||
|
|
||||||
|
rtsx_pci_read_config_dword(pcr, PCR_ASPM_SETTING_5260, &lval);
|
||||||
|
|
||||||
|
if (lval & ASPM_L1_1_EN_MASK)
|
||||||
|
rtsx_set_dev_flag(pcr, ASPM_L1_1_EN);
|
||||||
|
|
||||||
|
if (lval & ASPM_L1_2_EN_MASK)
|
||||||
|
rtsx_set_dev_flag(pcr, ASPM_L1_2_EN);
|
||||||
|
|
||||||
|
if (lval & PM_L1_1_EN_MASK)
|
||||||
|
rtsx_set_dev_flag(pcr, PM_L1_1_EN);
|
||||||
|
|
||||||
|
if (lval & PM_L1_2_EN_MASK)
|
||||||
|
rtsx_set_dev_flag(pcr, PM_L1_2_EN);
|
||||||
|
|
||||||
|
rts5260_pwr_saving_setting(pcr);
|
||||||
|
|
||||||
|
if (option->ltr_en) {
|
||||||
|
u16 val;
|
||||||
|
|
||||||
|
pcie_capability_read_word(pcr->pci, PCI_EXP_DEVCTL2, &val);
|
||||||
|
if (val & PCI_EXP_DEVCTL2_LTR_EN) {
|
||||||
|
option->ltr_enabled = true;
|
||||||
|
option->ltr_active = true;
|
||||||
|
rtsx_set_ltr_latency(pcr, option->ltr_active_latency);
|
||||||
|
} else {
|
||||||
|
option->ltr_enabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rtsx_check_dev_flag(pcr, ASPM_L1_1_EN | ASPM_L1_2_EN
|
||||||
|
| PM_L1_1_EN | PM_L1_2_EN))
|
||||||
|
option->force_clkreq_0 = false;
|
||||||
|
else
|
||||||
|
option->force_clkreq_0 = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rts5260_extra_init_hw(struct rtsx_pcr *pcr)
|
||||||
|
{
|
||||||
|
struct rtsx_cr_option *option = &pcr->option;
|
||||||
|
|
||||||
|
/* Set mcu_cnt to 7 to ensure data can be sampled properly */
|
||||||
|
rtsx_pci_write_register(pcr, 0xFC03, 0x7F, 0x07);
|
||||||
|
rtsx_pci_write_register(pcr, SSC_DIV_N_0, 0xFF, 0x5D);
|
||||||
|
|
||||||
|
rts5260_init_from_cfg(pcr);
|
||||||
|
|
||||||
|
/* force no MDIO*/
|
||||||
|
rtsx_pci_write_register(pcr, RTS5260_AUTOLOAD_CFG4,
|
||||||
|
0xFF, RTS5260_MIMO_DISABLE);
|
||||||
|
/*Modify SDVCC Tune Default Parameters!*/
|
||||||
|
rtsx_pci_write_register(pcr, LDO_VCC_CFG0,
|
||||||
|
RTS5260_DVCC_TUNE_MASK, RTS5260_DVCC_33);
|
||||||
|
|
||||||
|
rtsx_pci_write_register(pcr, PCLK_CTL, PCLK_MODE_SEL, PCLK_MODE_SEL);
|
||||||
|
|
||||||
|
rts5260_init_hw(pcr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced
|
||||||
|
* to drive low, and we forcibly request clock.
|
||||||
|
*/
|
||||||
|
if (option->force_clkreq_0)
|
||||||
|
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG,
|
||||||
|
FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW);
|
||||||
|
else
|
||||||
|
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG,
|
||||||
|
FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rts5260_set_aspm(struct rtsx_pcr *pcr, bool enable)
|
||||||
|
{
|
||||||
|
struct rtsx_cr_option *option = &pcr->option;
|
||||||
|
u8 val = 0;
|
||||||
|
|
||||||
|
if (pcr->aspm_enabled == enable)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (option->dev_aspm_mode == DEV_ASPM_DYNAMIC) {
|
||||||
|
if (enable)
|
||||||
|
val = pcr->aspm_en;
|
||||||
|
rtsx_pci_update_cfg_byte(pcr, pcr->pcie_cap + PCI_EXP_LNKCTL,
|
||||||
|
ASPM_MASK_NEG, val);
|
||||||
|
} else if (option->dev_aspm_mode == DEV_ASPM_BACKDOOR) {
|
||||||
|
u8 mask = FORCE_ASPM_VAL_MASK | FORCE_ASPM_CTL0;
|
||||||
|
|
||||||
|
if (!enable)
|
||||||
|
val = FORCE_ASPM_CTL0;
|
||||||
|
rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, mask, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
pcr->aspm_enabled = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rts5260_set_l1off_cfg_sub_d0(struct rtsx_pcr *pcr, int active)
|
||||||
|
{
|
||||||
|
struct rtsx_cr_option *option = &pcr->option;
|
||||||
|
u32 interrupt = rtsx_pci_readl(pcr, RTSX_BIPR);
|
||||||
|
int card_exist = (interrupt & SD_EXIST) | (interrupt & MS_EXIST);
|
||||||
|
int aspm_L1_1, aspm_L1_2;
|
||||||
|
u8 val = 0;
|
||||||
|
|
||||||
|
aspm_L1_1 = rtsx_check_dev_flag(pcr, ASPM_L1_1_EN);
|
||||||
|
aspm_L1_2 = rtsx_check_dev_flag(pcr, ASPM_L1_2_EN);
|
||||||
|
|
||||||
|
if (active) {
|
||||||
|
/* run, latency: 60us */
|
||||||
|
if (aspm_L1_1)
|
||||||
|
val = option->ltr_l1off_snooze_sspwrgate;
|
||||||
|
} else {
|
||||||
|
/* l1off, latency: 300us */
|
||||||
|
if (aspm_L1_2)
|
||||||
|
val = option->ltr_l1off_sspwrgate;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aspm_L1_1 || aspm_L1_2) {
|
||||||
|
if (rtsx_check_dev_flag(pcr,
|
||||||
|
LTR_L1SS_PWR_GATE_CHECK_CARD_EN)) {
|
||||||
|
if (card_exist)
|
||||||
|
val &= ~L1OFF_MBIAS2_EN_5250;
|
||||||
|
else
|
||||||
|
val |= L1OFF_MBIAS2_EN_5250;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rtsx_set_l1off_sub(pcr, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct pcr_ops rts5260_pcr_ops = {
|
||||||
|
.fetch_vendor_settings = rtsx_base_fetch_vendor_settings,
|
||||||
|
.turn_on_led = rts5260_turn_on_led,
|
||||||
|
.turn_off_led = rts5260_turn_off_led,
|
||||||
|
.extra_init_hw = rts5260_extra_init_hw,
|
||||||
|
.enable_auto_blink = rtsx_base_enable_auto_blink,
|
||||||
|
.disable_auto_blink = rtsx_base_disable_auto_blink,
|
||||||
|
.card_power_on = rts5260_card_power_on,
|
||||||
|
.card_power_off = rts5260_card_power_off,
|
||||||
|
.switch_output_voltage = rts5260_switch_output_voltage,
|
||||||
|
.force_power_down = rtsx_base_force_power_down,
|
||||||
|
.stop_cmd = rts5260_stop_cmd,
|
||||||
|
.set_aspm = rts5260_set_aspm,
|
||||||
|
.set_l1off_cfg_sub_d0 = rts5260_set_l1off_cfg_sub_d0,
|
||||||
|
.enable_ocp = rts5260_enable_ocp,
|
||||||
|
.disable_ocp = rts5260_disable_ocp,
|
||||||
|
.init_ocp = rts5260_init_ocp,
|
||||||
|
.process_ocp = rts5260_process_ocp,
|
||||||
|
.get_ocpstat = rts5260_get_ocpstat,
|
||||||
|
.clear_ocpstat = rts5260_clear_ocpstat,
|
||||||
|
};
|
||||||
|
|
||||||
|
void rts5260_init_params(struct rtsx_pcr *pcr)
|
||||||
|
{
|
||||||
|
struct rtsx_cr_option *option = &pcr->option;
|
||||||
|
struct rtsx_hw_param *hw_param = &pcr->hw_param;
|
||||||
|
|
||||||
|
pcr->extra_caps = EXTRA_CAPS_SD_SDR50 | EXTRA_CAPS_SD_SDR104;
|
||||||
|
pcr->num_slots = 2;
|
||||||
|
|
||||||
|
pcr->flags = 0;
|
||||||
|
pcr->card_drive_sel = RTSX_CARD_DRIVE_DEFAULT;
|
||||||
|
pcr->sd30_drive_sel_1v8 = CFG_DRIVER_TYPE_B;
|
||||||
|
pcr->sd30_drive_sel_3v3 = CFG_DRIVER_TYPE_B;
|
||||||
|
pcr->aspm_en = ASPM_L1_EN;
|
||||||
|
pcr->tx_initial_phase = SET_CLOCK_PHASE(1, 29, 16);
|
||||||
|
pcr->rx_initial_phase = SET_CLOCK_PHASE(24, 6, 5);
|
||||||
|
|
||||||
|
pcr->ic_version = rts5260_get_ic_version(pcr);
|
||||||
|
pcr->sd_pull_ctl_enable_tbl = rts5260_sd_pull_ctl_enable_tbl;
|
||||||
|
pcr->sd_pull_ctl_disable_tbl = rts5260_sd_pull_ctl_disable_tbl;
|
||||||
|
pcr->ms_pull_ctl_enable_tbl = rts5260_ms_pull_ctl_enable_tbl;
|
||||||
|
pcr->ms_pull_ctl_disable_tbl = rts5260_ms_pull_ctl_disable_tbl;
|
||||||
|
|
||||||
|
pcr->reg_pm_ctrl3 = RTS524A_PM_CTRL3;
|
||||||
|
|
||||||
|
pcr->ops = &rts5260_pcr_ops;
|
||||||
|
|
||||||
|
option->dev_flags = (LTR_L1SS_PWR_GATE_CHECK_CARD_EN
|
||||||
|
| LTR_L1SS_PWR_GATE_EN);
|
||||||
|
option->ltr_en = true;
|
||||||
|
|
||||||
|
/* init latency of active, idle, L1OFF to 60us, 300us, 3ms */
|
||||||
|
option->ltr_active_latency = LTR_ACTIVE_LATENCY_DEF;
|
||||||
|
option->ltr_idle_latency = LTR_IDLE_LATENCY_DEF;
|
||||||
|
option->ltr_l1off_latency = LTR_L1OFF_LATENCY_DEF;
|
||||||
|
option->dev_aspm_mode = DEV_ASPM_DYNAMIC;
|
||||||
|
option->l1_snooze_delay = L1_SNOOZE_DELAY_DEF;
|
||||||
|
option->ltr_l1off_sspwrgate = LTR_L1OFF_SSPWRGATE_5250_DEF;
|
||||||
|
option->ltr_l1off_snooze_sspwrgate =
|
||||||
|
LTR_L1OFF_SNOOZE_SSPWRGATE_5250_DEF;
|
||||||
|
|
||||||
|
option->ocp_en = 1;
|
||||||
|
if (option->ocp_en)
|
||||||
|
hw_param->interrupt_en |= SD_OC_INT_EN;
|
||||||
|
hw_param->ocp_glitch = SD_OCP_GLITCH_10M | SDVIO_OCP_GLITCH_800U;
|
||||||
|
option->sd_400mA_ocp_thd = RTS5260_DVCC_OCP_THD_550;
|
||||||
|
option->sd_800mA_ocp_thd = RTS5260_DVCC_OCP_THD_970;
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
#ifndef __RTS5260_H__
|
||||||
|
#define __RTS5260_H__
|
||||||
|
|
||||||
|
#define RTS5260_DVCC_CTRL 0xFF73
|
||||||
|
#define RTS5260_DVCC_OCP_EN (0x01 << 7)
|
||||||
|
#define RTS5260_DVCC_OCP_THD_MASK (0x07 << 4)
|
||||||
|
#define RTS5260_DVCC_POWERON (0x01 << 3)
|
||||||
|
#define RTS5260_DVCC_OCP_CL_EN (0x01 << 2)
|
||||||
|
|
||||||
|
#define RTS5260_DVIO_CTRL 0xFF75
|
||||||
|
#define RTS5260_DVIO_OCP_EN (0x01 << 7)
|
||||||
|
#define RTS5260_DVIO_OCP_THD_MASK (0x07 << 4)
|
||||||
|
#define RTS5260_DVIO_POWERON (0x01 << 3)
|
||||||
|
#define RTS5260_DVIO_OCP_CL_EN (0x01 << 2)
|
||||||
|
|
||||||
|
#define RTS5260_DV331812_CFG 0xFF71
|
||||||
|
#define RTS5260_DV331812_OCP_EN (0x01 << 7)
|
||||||
|
#define RTS5260_DV331812_OCP_THD_MASK (0x07 << 4)
|
||||||
|
#define RTS5260_DV331812_POWERON (0x01 << 3)
|
||||||
|
#define RTS5260_DV331812_SEL (0x01 << 2)
|
||||||
|
#define RTS5260_DV331812_VDD1 (0x01 << 2)
|
||||||
|
#define RTS5260_DV331812_VDD2 (0x00 << 2)
|
||||||
|
|
||||||
|
#define RTS5260_DV331812_OCP_THD_120 (0x00 << 4)
|
||||||
|
#define RTS5260_DV331812_OCP_THD_140 (0x01 << 4)
|
||||||
|
#define RTS5260_DV331812_OCP_THD_160 (0x02 << 4)
|
||||||
|
#define RTS5260_DV331812_OCP_THD_180 (0x03 << 4)
|
||||||
|
#define RTS5260_DV331812_OCP_THD_210 (0x04 << 4)
|
||||||
|
#define RTS5260_DV331812_OCP_THD_240 (0x05 << 4)
|
||||||
|
#define RTS5260_DV331812_OCP_THD_270 (0x06 << 4)
|
||||||
|
#define RTS5260_DV331812_OCP_THD_300 (0x07 << 4)
|
||||||
|
|
||||||
|
#define RTS5260_DVIO_OCP_THD_250 (0x00 << 4)
|
||||||
|
#define RTS5260_DVIO_OCP_THD_300 (0x01 << 4)
|
||||||
|
#define RTS5260_DVIO_OCP_THD_350 (0x02 << 4)
|
||||||
|
#define RTS5260_DVIO_OCP_THD_400 (0x03 << 4)
|
||||||
|
#define RTS5260_DVIO_OCP_THD_450 (0x04 << 4)
|
||||||
|
#define RTS5260_DVIO_OCP_THD_500 (0x05 << 4)
|
||||||
|
#define RTS5260_DVIO_OCP_THD_550 (0x06 << 4)
|
||||||
|
#define RTS5260_DVIO_OCP_THD_600 (0x07 << 4)
|
||||||
|
|
||||||
|
#define RTS5260_DVCC_OCP_THD_550 (0x00 << 4)
|
||||||
|
#define RTS5260_DVCC_OCP_THD_970 (0x05 << 4)
|
||||||
|
|
||||||
|
#endif
|
|
@ -29,7 +29,7 @@
|
||||||
#include <linux/idr.h>
|
#include <linux/idr.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/mfd/core.h>
|
#include <linux/mfd/core.h>
|
||||||
#include <linux/mfd/rtsx_pci.h>
|
#include <linux/rtsx_pci.h>
|
||||||
#include <linux/mmc/card.h>
|
#include <linux/mmc/card.h>
|
||||||
#include <asm/unaligned.h>
|
#include <asm/unaligned.h>
|
||||||
|
|
||||||
|
@ -62,6 +62,7 @@ static const struct pci_device_id rtsx_pci_ids[] = {
|
||||||
{ PCI_DEVICE(0x10EC, 0x5286), PCI_CLASS_OTHERS << 16, 0xFF0000 },
|
{ PCI_DEVICE(0x10EC, 0x5286), PCI_CLASS_OTHERS << 16, 0xFF0000 },
|
||||||
{ PCI_DEVICE(0x10EC, 0x524A), PCI_CLASS_OTHERS << 16, 0xFF0000 },
|
{ PCI_DEVICE(0x10EC, 0x524A), PCI_CLASS_OTHERS << 16, 0xFF0000 },
|
||||||
{ PCI_DEVICE(0x10EC, 0x525A), PCI_CLASS_OTHERS << 16, 0xFF0000 },
|
{ PCI_DEVICE(0x10EC, 0x525A), PCI_CLASS_OTHERS << 16, 0xFF0000 },
|
||||||
|
{ PCI_DEVICE(0x10EC, 0x5260), PCI_CLASS_OTHERS << 16, 0xFF0000 },
|
||||||
{ 0, }
|
{ 0, }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -334,6 +335,9 @@ EXPORT_SYMBOL_GPL(rtsx_pci_read_phy_register);
|
||||||
|
|
||||||
void rtsx_pci_stop_cmd(struct rtsx_pcr *pcr)
|
void rtsx_pci_stop_cmd(struct rtsx_pcr *pcr)
|
||||||
{
|
{
|
||||||
|
if (pcr->ops->stop_cmd)
|
||||||
|
return pcr->ops->stop_cmd(pcr);
|
||||||
|
|
||||||
rtsx_pci_writel(pcr, RTSX_HCBCTLR, STOP_CMD);
|
rtsx_pci_writel(pcr, RTSX_HCBCTLR, STOP_CMD);
|
||||||
rtsx_pci_writel(pcr, RTSX_HDBCTLR, STOP_DMA);
|
rtsx_pci_writel(pcr, RTSX_HDBCTLR, STOP_DMA);
|
||||||
|
|
||||||
|
@ -826,7 +830,7 @@ int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock,
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
/* Wait SSC clock stable */
|
/* Wait SSC clock stable */
|
||||||
udelay(10);
|
udelay(SSC_CLOCK_STABLE_WAIT);
|
||||||
err = rtsx_pci_write_register(pcr, CLK_CTL, CLK_LOW_FREQ, 0);
|
err = rtsx_pci_write_register(pcr, CLK_CTL, CLK_LOW_FREQ, 0);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
@ -963,6 +967,20 @@ static void rtsx_pci_card_detect(struct work_struct *work)
|
||||||
pcr->slots[RTSX_MS_CARD].p_dev);
|
pcr->slots[RTSX_MS_CARD].p_dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rtsx_pci_process_ocp(struct rtsx_pcr *pcr)
|
||||||
|
{
|
||||||
|
if (pcr->ops->process_ocp)
|
||||||
|
pcr->ops->process_ocp(pcr);
|
||||||
|
}
|
||||||
|
|
||||||
|
int rtsx_pci_process_ocp_interrupt(struct rtsx_pcr *pcr)
|
||||||
|
{
|
||||||
|
if (pcr->option.ocp_en)
|
||||||
|
rtsx_pci_process_ocp(pcr);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static irqreturn_t rtsx_pci_isr(int irq, void *dev_id)
|
static irqreturn_t rtsx_pci_isr(int irq, void *dev_id)
|
||||||
{
|
{
|
||||||
struct rtsx_pcr *pcr = dev_id;
|
struct rtsx_pcr *pcr = dev_id;
|
||||||
|
@ -987,6 +1005,9 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id)
|
||||||
|
|
||||||
int_reg &= (pcr->bier | 0x7FFFFF);
|
int_reg &= (pcr->bier | 0x7FFFFF);
|
||||||
|
|
||||||
|
if (int_reg & SD_OC_INT)
|
||||||
|
rtsx_pci_process_ocp_interrupt(pcr);
|
||||||
|
|
||||||
if (int_reg & SD_INT) {
|
if (int_reg & SD_INT) {
|
||||||
if (int_reg & SD_EXIST) {
|
if (int_reg & SD_EXIST) {
|
||||||
pcr->card_inserted |= SD_EXIST;
|
pcr->card_inserted |= SD_EXIST;
|
||||||
|
@ -1119,6 +1140,102 @@ static void rtsx_pci_power_off(struct rtsx_pcr *pcr, u8 pm_state)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void rtsx_pci_enable_ocp(struct rtsx_pcr *pcr)
|
||||||
|
{
|
||||||
|
u8 val = SD_OCP_INT_EN | SD_DETECT_EN;
|
||||||
|
|
||||||
|
if (pcr->ops->enable_ocp)
|
||||||
|
pcr->ops->enable_ocp(pcr);
|
||||||
|
else
|
||||||
|
rtsx_pci_write_register(pcr, REG_OCPCTL, 0xFF, val);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void rtsx_pci_disable_ocp(struct rtsx_pcr *pcr)
|
||||||
|
{
|
||||||
|
u8 mask = SD_OCP_INT_EN | SD_DETECT_EN;
|
||||||
|
|
||||||
|
if (pcr->ops->disable_ocp)
|
||||||
|
pcr->ops->disable_ocp(pcr);
|
||||||
|
else
|
||||||
|
rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rtsx_pci_init_ocp(struct rtsx_pcr *pcr)
|
||||||
|
{
|
||||||
|
if (pcr->ops->init_ocp) {
|
||||||
|
pcr->ops->init_ocp(pcr);
|
||||||
|
} else {
|
||||||
|
struct rtsx_cr_option *option = &(pcr->option);
|
||||||
|
|
||||||
|
if (option->ocp_en) {
|
||||||
|
u8 val = option->sd_400mA_ocp_thd;
|
||||||
|
|
||||||
|
rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN, 0);
|
||||||
|
rtsx_pci_write_register(pcr, REG_OCPPARA1,
|
||||||
|
SD_OCP_TIME_MASK, SD_OCP_TIME_800);
|
||||||
|
rtsx_pci_write_register(pcr, REG_OCPPARA2,
|
||||||
|
SD_OCP_THD_MASK, val);
|
||||||
|
rtsx_pci_write_register(pcr, REG_OCPGLITCH,
|
||||||
|
SD_OCP_GLITCH_MASK, pcr->hw_param.ocp_glitch);
|
||||||
|
rtsx_pci_enable_ocp(pcr);
|
||||||
|
} else {
|
||||||
|
/* OC power down */
|
||||||
|
rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN,
|
||||||
|
OC_POWER_DOWN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int rtsx_pci_get_ocpstat(struct rtsx_pcr *pcr, u8 *val)
|
||||||
|
{
|
||||||
|
if (pcr->ops->get_ocpstat)
|
||||||
|
return pcr->ops->get_ocpstat(pcr, val);
|
||||||
|
else
|
||||||
|
return rtsx_pci_read_register(pcr, REG_OCPSTAT, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rtsx_pci_clear_ocpstat(struct rtsx_pcr *pcr)
|
||||||
|
{
|
||||||
|
if (pcr->ops->clear_ocpstat) {
|
||||||
|
pcr->ops->clear_ocpstat(pcr);
|
||||||
|
} else {
|
||||||
|
u8 mask = SD_OCP_INT_CLR | SD_OC_CLR;
|
||||||
|
u8 val = SD_OCP_INT_CLR | SD_OC_CLR;
|
||||||
|
|
||||||
|
rtsx_pci_write_register(pcr, REG_OCPCTL, mask, val);
|
||||||
|
rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int rtsx_sd_power_off_card3v3(struct rtsx_pcr *pcr)
|
||||||
|
{
|
||||||
|
rtsx_pci_write_register(pcr, CARD_CLK_EN, SD_CLK_EN |
|
||||||
|
MS_CLK_EN | SD40_CLK_EN, 0);
|
||||||
|
rtsx_pci_write_register(pcr, CARD_OE, SD_OUTPUT_EN, 0);
|
||||||
|
|
||||||
|
rtsx_pci_card_power_off(pcr, RTSX_SD_CARD);
|
||||||
|
|
||||||
|
msleep(50);
|
||||||
|
|
||||||
|
rtsx_pci_card_pull_ctl_disable(pcr, RTSX_SD_CARD);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rtsx_ms_power_off_card3v3(struct rtsx_pcr *pcr)
|
||||||
|
{
|
||||||
|
rtsx_pci_write_register(pcr, CARD_CLK_EN, SD_CLK_EN |
|
||||||
|
MS_CLK_EN | SD40_CLK_EN, 0);
|
||||||
|
|
||||||
|
rtsx_pci_card_pull_ctl_disable(pcr, RTSX_MS_CARD);
|
||||||
|
|
||||||
|
rtsx_pci_write_register(pcr, CARD_OE, MS_OUTPUT_EN, 0);
|
||||||
|
rtsx_pci_card_power_off(pcr, RTSX_MS_CARD);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int rtsx_pci_init_hw(struct rtsx_pcr *pcr)
|
static int rtsx_pci_init_hw(struct rtsx_pcr *pcr)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
@ -1189,6 +1306,7 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr)
|
||||||
case PID_5250:
|
case PID_5250:
|
||||||
case PID_524A:
|
case PID_524A:
|
||||||
case PID_525A:
|
case PID_525A:
|
||||||
|
case PID_5260:
|
||||||
rtsx_pci_write_register(pcr, PM_CLK_FORCE_CTL, 1, 1);
|
rtsx_pci_write_register(pcr, PM_CLK_FORCE_CTL, 1, 1);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -1265,6 +1383,9 @@ static int rtsx_pci_init_chip(struct rtsx_pcr *pcr)
|
||||||
case 0x5286:
|
case 0x5286:
|
||||||
rtl8402_init_params(pcr);
|
rtl8402_init_params(pcr);
|
||||||
break;
|
break;
|
||||||
|
case 0x5260:
|
||||||
|
rts5260_init_params(pcr);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
pcr_dbg(pcr, "PID: 0x%04x, IC version: 0x%02x\n",
|
pcr_dbg(pcr, "PID: 0x%04x, IC version: 0x%02x\n",
|
|
@ -22,7 +22,7 @@
|
||||||
#ifndef __RTSX_PCR_H
|
#ifndef __RTSX_PCR_H
|
||||||
#define __RTSX_PCR_H
|
#define __RTSX_PCR_H
|
||||||
|
|
||||||
#include <linux/mfd/rtsx_pci.h>
|
#include <linux/rtsx_pci.h>
|
||||||
|
|
||||||
#define MIN_DIV_N_PCR 80
|
#define MIN_DIV_N_PCR 80
|
||||||
#define MAX_DIV_N_PCR 208
|
#define MAX_DIV_N_PCR 208
|
||||||
|
@ -44,6 +44,8 @@
|
||||||
#define ASPM_MASK_NEG 0xFC
|
#define ASPM_MASK_NEG 0xFC
|
||||||
#define MASK_8_BIT_DEF 0xFF
|
#define MASK_8_BIT_DEF 0xFF
|
||||||
|
|
||||||
|
#define SSC_CLOCK_STABLE_WAIT 130
|
||||||
|
|
||||||
int __rtsx_pci_write_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 val);
|
int __rtsx_pci_write_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 val);
|
||||||
int __rtsx_pci_read_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 *val);
|
int __rtsx_pci_read_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 *val);
|
||||||
|
|
||||||
|
@ -57,6 +59,7 @@ void rts5249_init_params(struct rtsx_pcr *pcr);
|
||||||
void rts524a_init_params(struct rtsx_pcr *pcr);
|
void rts524a_init_params(struct rtsx_pcr *pcr);
|
||||||
void rts525a_init_params(struct rtsx_pcr *pcr);
|
void rts525a_init_params(struct rtsx_pcr *pcr);
|
||||||
void rtl8411b_init_params(struct rtsx_pcr *pcr);
|
void rtl8411b_init_params(struct rtsx_pcr *pcr);
|
||||||
|
void rts5260_init_params(struct rtsx_pcr *pcr);
|
||||||
|
|
||||||
static inline u8 map_sd_drive(int idx)
|
static inline u8 map_sd_drive(int idx)
|
||||||
{
|
{
|
||||||
|
@ -99,5 +102,12 @@ do { \
|
||||||
int rtsx_gops_pm_reset(struct rtsx_pcr *pcr);
|
int rtsx_gops_pm_reset(struct rtsx_pcr *pcr);
|
||||||
int rtsx_set_ltr_latency(struct rtsx_pcr *pcr, u32 latency);
|
int rtsx_set_ltr_latency(struct rtsx_pcr *pcr, u32 latency);
|
||||||
int rtsx_set_l1off_sub(struct rtsx_pcr *pcr, u8 val);
|
int rtsx_set_l1off_sub(struct rtsx_pcr *pcr, u8 val);
|
||||||
|
void rtsx_pci_init_ocp(struct rtsx_pcr *pcr);
|
||||||
|
void rtsx_pci_disable_ocp(struct rtsx_pcr *pcr);
|
||||||
|
void rtsx_pci_enable_ocp(struct rtsx_pcr *pcr);
|
||||||
|
int rtsx_pci_get_ocpstat(struct rtsx_pcr *pcr, u8 *val);
|
||||||
|
void rtsx_pci_clear_ocpstat(struct rtsx_pcr *pcr);
|
||||||
|
int rtsx_sd_power_off_card3v3(struct rtsx_pcr *pcr);
|
||||||
|
int rtsx_ms_power_off_card3v3(struct rtsx_pcr *pcr);
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -23,7 +23,7 @@
|
||||||
#include <linux/usb.h>
|
#include <linux/usb.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/mfd/core.h>
|
#include <linux/mfd/core.h>
|
||||||
#include <linux/mfd/rtsx_usb.h>
|
#include <linux/rtsx_usb.h>
|
||||||
|
|
||||||
static int polling_pipe = 1;
|
static int polling_pipe = 1;
|
||||||
module_param(polling_pipe, int, S_IRUGO | S_IWUSR);
|
module_param(polling_pipe, int, S_IRUGO | S_IWUSR);
|
|
@ -838,14 +838,14 @@ config MMC_USDHI6ROL0
|
||||||
|
|
||||||
config MMC_REALTEK_PCI
|
config MMC_REALTEK_PCI
|
||||||
tristate "Realtek PCI-E SD/MMC Card Interface Driver"
|
tristate "Realtek PCI-E SD/MMC Card Interface Driver"
|
||||||
depends on MFD_RTSX_PCI
|
depends on MISC_RTSX_PCI
|
||||||
help
|
help
|
||||||
Say Y here to include driver code to support SD/MMC card interface
|
Say Y here to include driver code to support SD/MMC card interface
|
||||||
of Realtek PCI-E card reader
|
of Realtek PCI-E card reader
|
||||||
|
|
||||||
config MMC_REALTEK_USB
|
config MMC_REALTEK_USB
|
||||||
tristate "Realtek USB SD/MMC Card Interface Driver"
|
tristate "Realtek USB SD/MMC Card Interface Driver"
|
||||||
depends on MFD_RTSX_USB
|
depends on MISC_RTSX_USB
|
||||||
help
|
help
|
||||||
Say Y here to include driver code to support SD/MMC card interface
|
Say Y here to include driver code to support SD/MMC card interface
|
||||||
of Realtek RTS5129/39 series card reader
|
of Realtek RTS5129/39 series card reader
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
#include <linux/mmc/sd.h>
|
#include <linux/mmc/sd.h>
|
||||||
#include <linux/mmc/sdio.h>
|
#include <linux/mmc/sdio.h>
|
||||||
#include <linux/mmc/card.h>
|
#include <linux/mmc/card.h>
|
||||||
#include <linux/mfd/rtsx_pci.h>
|
#include <linux/rtsx_pci.h>
|
||||||
#include <asm/unaligned.h>
|
#include <asm/unaligned.h>
|
||||||
|
|
||||||
struct realtek_pci_sdmmc {
|
struct realtek_pci_sdmmc {
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
#include <linux/scatterlist.h>
|
#include <linux/scatterlist.h>
|
||||||
#include <linux/pm_runtime.h>
|
#include <linux/pm_runtime.h>
|
||||||
|
|
||||||
#include <linux/mfd/rtsx_usb.h>
|
#include <linux/rtsx_usb.h>
|
||||||
#include <asm/unaligned.h>
|
#include <asm/unaligned.h>
|
||||||
|
|
||||||
#if defined(CONFIG_LEDS_CLASS) || (defined(CONFIG_LEDS_CLASS_MODULE) && \
|
#if defined(CONFIG_LEDS_CLASS) || (defined(CONFIG_LEDS_CLASS_MODULE) && \
|
||||||
|
|
|
@ -38,14 +38,8 @@ config CHROMEOS_PSTORE
|
||||||
If you have a supported Chromebook, choose Y or M here.
|
If you have a supported Chromebook, choose Y or M here.
|
||||||
The module will be called chromeos_pstore.
|
The module will be called chromeos_pstore.
|
||||||
|
|
||||||
config CROS_EC_CHARDEV
|
config CROS_EC_CTL
|
||||||
tristate "Chrome OS Embedded Controller userspace device interface"
|
tristate
|
||||||
depends on MFD_CROS_EC
|
|
||||||
---help---
|
|
||||||
This driver adds support to talk with the ChromeOS EC from userspace.
|
|
||||||
|
|
||||||
If you have a supported Chromebook, choose Y or M here.
|
|
||||||
The module will be called cros_ec_dev.
|
|
||||||
|
|
||||||
config CROS_EC_LPC
|
config CROS_EC_LPC
|
||||||
tristate "ChromeOS Embedded Controller (LPC)"
|
tristate "ChromeOS Embedded Controller (LPC)"
|
||||||
|
|
|
@ -2,10 +2,9 @@
|
||||||
|
|
||||||
obj-$(CONFIG_CHROMEOS_LAPTOP) += chromeos_laptop.o
|
obj-$(CONFIG_CHROMEOS_LAPTOP) += chromeos_laptop.o
|
||||||
obj-$(CONFIG_CHROMEOS_PSTORE) += chromeos_pstore.o
|
obj-$(CONFIG_CHROMEOS_PSTORE) += chromeos_pstore.o
|
||||||
cros_ec_devs-objs := cros_ec_dev.o cros_ec_sysfs.o \
|
cros_ec_ctl-objs := cros_ec_sysfs.o cros_ec_lightbar.o \
|
||||||
cros_ec_lightbar.o cros_ec_vbc.o \
|
cros_ec_vbc.o cros_ec_debugfs.o
|
||||||
cros_ec_debugfs.o
|
obj-$(CONFIG_CROS_EC_CTL) += cros_ec_ctl.o
|
||||||
obj-$(CONFIG_CROS_EC_CHARDEV) += cros_ec_devs.o
|
|
||||||
cros_ec_lpcs-objs := cros_ec_lpc.o cros_ec_lpc_reg.o
|
cros_ec_lpcs-objs := cros_ec_lpc.o cros_ec_lpc_reg.o
|
||||||
cros_ec_lpcs-$(CONFIG_CROS_EC_LPC_MEC) += cros_ec_lpc_mec.o
|
cros_ec_lpcs-$(CONFIG_CROS_EC_LPC_MEC) += cros_ec_lpc_mec.o
|
||||||
obj-$(CONFIG_CROS_EC_LPC) += cros_ec_lpcs.o
|
obj-$(CONFIG_CROS_EC_LPC) += cros_ec_lpcs.o
|
||||||
|
|
|
@ -29,9 +29,6 @@
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/wait.h>
|
#include <linux/wait.h>
|
||||||
|
|
||||||
#include "cros_ec_dev.h"
|
|
||||||
#include "cros_ec_debugfs.h"
|
|
||||||
|
|
||||||
#define LOG_SHIFT 14
|
#define LOG_SHIFT 14
|
||||||
#define LOG_SIZE (1 << LOG_SHIFT)
|
#define LOG_SIZE (1 << LOG_SHIFT)
|
||||||
#define LOG_POLL_SEC 10
|
#define LOG_POLL_SEC 10
|
||||||
|
@ -390,6 +387,7 @@ remove_debugfs:
|
||||||
debugfs_remove_recursive(debug_info->dir);
|
debugfs_remove_recursive(debug_info->dir);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(cros_ec_debugfs_init);
|
||||||
|
|
||||||
void cros_ec_debugfs_remove(struct cros_ec_dev *ec)
|
void cros_ec_debugfs_remove(struct cros_ec_dev *ec)
|
||||||
{
|
{
|
||||||
|
@ -399,3 +397,4 @@ void cros_ec_debugfs_remove(struct cros_ec_dev *ec)
|
||||||
debugfs_remove_recursive(ec->debug_info->dir);
|
debugfs_remove_recursive(ec->debug_info->dir);
|
||||||
cros_ec_cleanup_console_log(ec->debug_info);
|
cros_ec_cleanup_console_log(ec->debug_info);
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(cros_ec_debugfs_remove);
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2015 Google, Inc.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _DRV_CROS_EC_DEBUGFS_H_
|
|
||||||
#define _DRV_CROS_EC_DEBUGFS_H_
|
|
||||||
|
|
||||||
#include "cros_ec_dev.h"
|
|
||||||
|
|
||||||
/* debugfs stuff */
|
|
||||||
int cros_ec_debugfs_init(struct cros_ec_dev *ec);
|
|
||||||
void cros_ec_debugfs_remove(struct cros_ec_dev *ec);
|
|
||||||
|
|
||||||
#endif /* _DRV_CROS_EC_DEBUGFS_H_ */
|
|
|
@ -33,8 +33,6 @@
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
|
||||||
#include "cros_ec_dev.h"
|
|
||||||
|
|
||||||
/* Rate-limit the lightbar interface to prevent DoS. */
|
/* Rate-limit the lightbar interface to prevent DoS. */
|
||||||
static unsigned long lb_interval_jiffies = 50 * HZ / 1000;
|
static unsigned long lb_interval_jiffies = 50 * HZ / 1000;
|
||||||
|
|
||||||
|
@ -414,6 +412,7 @@ error:
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(lb_manual_suspend_ctrl);
|
||||||
|
|
||||||
int lb_suspend(struct cros_ec_dev *ec)
|
int lb_suspend(struct cros_ec_dev *ec)
|
||||||
{
|
{
|
||||||
|
@ -422,6 +421,7 @@ int lb_suspend(struct cros_ec_dev *ec)
|
||||||
|
|
||||||
return lb_send_empty_cmd(ec, LIGHTBAR_CMD_SUSPEND);
|
return lb_send_empty_cmd(ec, LIGHTBAR_CMD_SUSPEND);
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(lb_suspend);
|
||||||
|
|
||||||
int lb_resume(struct cros_ec_dev *ec)
|
int lb_resume(struct cros_ec_dev *ec)
|
||||||
{
|
{
|
||||||
|
@ -430,6 +430,7 @@ int lb_resume(struct cros_ec_dev *ec)
|
||||||
|
|
||||||
return lb_send_empty_cmd(ec, LIGHTBAR_CMD_RESUME);
|
return lb_send_empty_cmd(ec, LIGHTBAR_CMD_RESUME);
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(lb_resume);
|
||||||
|
|
||||||
static ssize_t sequence_store(struct device *dev, struct device_attribute *attr,
|
static ssize_t sequence_store(struct device *dev, struct device_attribute *attr,
|
||||||
const char *buf, size_t count)
|
const char *buf, size_t count)
|
||||||
|
@ -622,3 +623,4 @@ struct attribute_group cros_ec_lightbar_attr_group = {
|
||||||
.attrs = __lb_cmds_attrs,
|
.attrs = __lb_cmds_attrs,
|
||||||
.is_visible = cros_ec_lightbar_attrs_are_visible,
|
.is_visible = cros_ec_lightbar_attrs_are_visible,
|
||||||
};
|
};
|
||||||
|
EXPORT_SYMBOL(cros_ec_lightbar_attr_group);
|
||||||
|
|
|
@ -34,8 +34,6 @@
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
|
|
||||||
#include "cros_ec_dev.h"
|
|
||||||
|
|
||||||
/* Accessor functions */
|
/* Accessor functions */
|
||||||
|
|
||||||
static ssize_t show_ec_reboot(struct device *dev,
|
static ssize_t show_ec_reboot(struct device *dev,
|
||||||
|
@ -294,4 +292,7 @@ static struct attribute *__ec_attrs[] = {
|
||||||
struct attribute_group cros_ec_attr_group = {
|
struct attribute_group cros_ec_attr_group = {
|
||||||
.attrs = __ec_attrs,
|
.attrs = __ec_attrs,
|
||||||
};
|
};
|
||||||
|
EXPORT_SYMBOL(cros_ec_attr_group);
|
||||||
|
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_DESCRIPTION("ChromeOS EC control driver");
|
||||||
|
|
|
@ -135,3 +135,4 @@ struct attribute_group cros_ec_vbc_attr_group = {
|
||||||
.bin_attrs = cros_ec_vbc_bin_attrs,
|
.bin_attrs = cros_ec_vbc_bin_attrs,
|
||||||
.is_bin_visible = cros_ec_vbc_is_visible,
|
.is_bin_visible = cros_ec_vbc_is_visible,
|
||||||
};
|
};
|
||||||
|
EXPORT_SYMBOL(cros_ec_vbc_attr_group);
|
||||||
|
|
|
@ -132,6 +132,33 @@ void serdev_device_close(struct serdev_device *serdev)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(serdev_device_close);
|
EXPORT_SYMBOL_GPL(serdev_device_close);
|
||||||
|
|
||||||
|
static void devm_serdev_device_release(struct device *dev, void *dr)
|
||||||
|
{
|
||||||
|
serdev_device_close(*(struct serdev_device **)dr);
|
||||||
|
}
|
||||||
|
|
||||||
|
int devm_serdev_device_open(struct device *dev, struct serdev_device *serdev)
|
||||||
|
{
|
||||||
|
struct serdev_device **dr;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
dr = devres_alloc(devm_serdev_device_release, sizeof(*dr), GFP_KERNEL);
|
||||||
|
if (!dr)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
ret = serdev_device_open(serdev);
|
||||||
|
if (ret) {
|
||||||
|
devres_free(dr);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
*dr = serdev;
|
||||||
|
devres_add(dev, dr);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(devm_serdev_device_open);
|
||||||
|
|
||||||
void serdev_device_write_wakeup(struct serdev_device *serdev)
|
void serdev_device_write_wakeup(struct serdev_device *serdev)
|
||||||
{
|
{
|
||||||
complete(&serdev->write_comp);
|
complete(&serdev->write_comp);
|
||||||
|
@ -268,8 +295,8 @@ static int serdev_drv_probe(struct device *dev)
|
||||||
static int serdev_drv_remove(struct device *dev)
|
static int serdev_drv_remove(struct device *dev)
|
||||||
{
|
{
|
||||||
const struct serdev_device_driver *sdrv = to_serdev_device_driver(dev->driver);
|
const struct serdev_device_driver *sdrv = to_serdev_device_driver(dev->driver);
|
||||||
|
if (sdrv->remove)
|
||||||
sdrv->remove(to_serdev_device(dev));
|
sdrv->remove(to_serdev_device(dev));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -223,6 +223,13 @@ config ZIIRAVE_WATCHDOG
|
||||||
To compile this driver as a module, choose M here: the
|
To compile this driver as a module, choose M here: the
|
||||||
module will be called ziirave_wdt.
|
module will be called ziirave_wdt.
|
||||||
|
|
||||||
|
config RAVE_SP_WATCHDOG
|
||||||
|
tristate "RAVE SP Watchdog timer"
|
||||||
|
depends on RAVE_SP_CORE
|
||||||
|
select WATCHDOG_CORE
|
||||||
|
help
|
||||||
|
Support for the watchdog on RAVE SP device.
|
||||||
|
|
||||||
# ALPHA Architecture
|
# ALPHA Architecture
|
||||||
|
|
||||||
# ARM Architecture
|
# ARM Architecture
|
||||||
|
|
|
@ -224,3 +224,4 @@ obj-$(CONFIG_MAX77620_WATCHDOG) += max77620_wdt.o
|
||||||
obj-$(CONFIG_ZIIRAVE_WATCHDOG) += ziirave_wdt.o
|
obj-$(CONFIG_ZIIRAVE_WATCHDOG) += ziirave_wdt.o
|
||||||
obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o
|
obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o
|
||||||
obj-$(CONFIG_MENF21BMC_WATCHDOG) += menf21bmc_wdt.o
|
obj-$(CONFIG_MENF21BMC_WATCHDOG) += menf21bmc_wdt.o
|
||||||
|
obj-$(CONFIG_RAVE_SP_WATCHDOG) += rave-sp-wdt.o
|
||||||
|
|
|
@ -0,0 +1,337 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Driver for watchdog aspect of for Zodiac Inflight Innovations RAVE
|
||||||
|
* Supervisory Processor(SP) MCU
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 Zodiac Inflight Innovation
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/delay.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/mfd/rave-sp.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/nvmem-consumer.h>
|
||||||
|
#include <linux/of_device.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/reboot.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/watchdog.h>
|
||||||
|
|
||||||
|
enum {
|
||||||
|
RAVE_SP_RESET_BYTE = 1,
|
||||||
|
RAVE_SP_RESET_REASON_NORMAL = 0,
|
||||||
|
RAVE_SP_RESET_DELAY_MS = 500,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct rave_sp_wdt_variant - RAVE SP watchdog variant
|
||||||
|
*
|
||||||
|
* @max_timeout: Largest possible watchdog timeout setting
|
||||||
|
* @min_timeout: Smallest possible watchdog timeout setting
|
||||||
|
*
|
||||||
|
* @configure: Function to send configuration command
|
||||||
|
* @restart: Function to send "restart" command
|
||||||
|
*/
|
||||||
|
struct rave_sp_wdt_variant {
|
||||||
|
unsigned int max_timeout;
|
||||||
|
unsigned int min_timeout;
|
||||||
|
|
||||||
|
int (*configure)(struct watchdog_device *, bool);
|
||||||
|
int (*restart)(struct watchdog_device *);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct rave_sp_wdt - RAVE SP watchdog
|
||||||
|
*
|
||||||
|
* @wdd: Underlying watchdog device
|
||||||
|
* @sp: Pointer to parent RAVE SP device
|
||||||
|
* @variant: Device specific variant information
|
||||||
|
* @reboot_notifier: Reboot notifier implementing machine reset
|
||||||
|
*/
|
||||||
|
struct rave_sp_wdt {
|
||||||
|
struct watchdog_device wdd;
|
||||||
|
struct rave_sp *sp;
|
||||||
|
const struct rave_sp_wdt_variant *variant;
|
||||||
|
struct notifier_block reboot_notifier;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct rave_sp_wdt *to_rave_sp_wdt(struct watchdog_device *wdd)
|
||||||
|
{
|
||||||
|
return container_of(wdd, struct rave_sp_wdt, wdd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rave_sp_wdt_exec(struct watchdog_device *wdd, void *data,
|
||||||
|
size_t data_size)
|
||||||
|
{
|
||||||
|
return rave_sp_exec(to_rave_sp_wdt(wdd)->sp,
|
||||||
|
data, data_size, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rave_sp_wdt_legacy_configure(struct watchdog_device *wdd, bool on)
|
||||||
|
{
|
||||||
|
u8 cmd[] = {
|
||||||
|
[0] = RAVE_SP_CMD_SW_WDT,
|
||||||
|
[1] = 0,
|
||||||
|
[2] = 0,
|
||||||
|
[3] = on,
|
||||||
|
[4] = on ? wdd->timeout : 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
return rave_sp_wdt_exec(wdd, cmd, sizeof(cmd));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rave_sp_wdt_rdu_configure(struct watchdog_device *wdd, bool on)
|
||||||
|
{
|
||||||
|
u8 cmd[] = {
|
||||||
|
[0] = RAVE_SP_CMD_SW_WDT,
|
||||||
|
[1] = 0,
|
||||||
|
[2] = on,
|
||||||
|
[3] = (u8)wdd->timeout,
|
||||||
|
[4] = (u8)(wdd->timeout >> 8),
|
||||||
|
};
|
||||||
|
|
||||||
|
return rave_sp_wdt_exec(wdd, cmd, sizeof(cmd));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rave_sp_wdt_configure - Configure watchdog device
|
||||||
|
*
|
||||||
|
* @wdd: Device to configure
|
||||||
|
* @on: Desired state of the watchdog timer (ON/OFF)
|
||||||
|
*
|
||||||
|
* This function configures two aspects of the watchdog timer:
|
||||||
|
*
|
||||||
|
* - Wheither it is ON or OFF
|
||||||
|
* - Its timeout duration
|
||||||
|
*
|
||||||
|
* with first aspect specified via function argument and second via
|
||||||
|
* the value of 'wdd->timeout'.
|
||||||
|
*/
|
||||||
|
static int rave_sp_wdt_configure(struct watchdog_device *wdd, bool on)
|
||||||
|
{
|
||||||
|
return to_rave_sp_wdt(wdd)->variant->configure(wdd, on);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rave_sp_wdt_legacy_restart(struct watchdog_device *wdd)
|
||||||
|
{
|
||||||
|
u8 cmd[] = {
|
||||||
|
[0] = RAVE_SP_CMD_RESET,
|
||||||
|
[1] = 0,
|
||||||
|
[2] = RAVE_SP_RESET_BYTE
|
||||||
|
};
|
||||||
|
|
||||||
|
return rave_sp_wdt_exec(wdd, cmd, sizeof(cmd));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rave_sp_wdt_rdu_restart(struct watchdog_device *wdd)
|
||||||
|
{
|
||||||
|
u8 cmd[] = {
|
||||||
|
[0] = RAVE_SP_CMD_RESET,
|
||||||
|
[1] = 0,
|
||||||
|
[2] = RAVE_SP_RESET_BYTE,
|
||||||
|
[3] = RAVE_SP_RESET_REASON_NORMAL
|
||||||
|
};
|
||||||
|
|
||||||
|
return rave_sp_wdt_exec(wdd, cmd, sizeof(cmd));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rave_sp_wdt_reboot_notifier(struct notifier_block *nb,
|
||||||
|
unsigned long action, void *data)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Restart handler is called in atomic context which means we
|
||||||
|
* can't communicate to SP via UART. Luckily for use SP will
|
||||||
|
* wait 500ms before actually resetting us, so we ask it to do
|
||||||
|
* so here and let the rest of the system go on wrapping
|
||||||
|
* things up.
|
||||||
|
*/
|
||||||
|
if (action == SYS_DOWN || action == SYS_HALT) {
|
||||||
|
struct rave_sp_wdt *sp_wd =
|
||||||
|
container_of(nb, struct rave_sp_wdt, reboot_notifier);
|
||||||
|
|
||||||
|
const int ret = sp_wd->variant->restart(&sp_wd->wdd);
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
dev_err(sp_wd->wdd.parent,
|
||||||
|
"Failed to issue restart command (%d)", ret);
|
||||||
|
return NOTIFY_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NOTIFY_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rave_sp_wdt_restart(struct watchdog_device *wdd,
|
||||||
|
unsigned long action, void *data)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* The actual work was done by reboot notifier above. SP
|
||||||
|
* firmware waits 500 ms before issuing reset, so let's hang
|
||||||
|
* here for twice that delay and hopefuly we'd never reach
|
||||||
|
* the return statement.
|
||||||
|
*/
|
||||||
|
mdelay(2 * RAVE_SP_RESET_DELAY_MS);
|
||||||
|
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rave_sp_wdt_start(struct watchdog_device *wdd)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = rave_sp_wdt_configure(wdd, true);
|
||||||
|
if (!ret)
|
||||||
|
set_bit(WDOG_HW_RUNNING, &wdd->status);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rave_sp_wdt_stop(struct watchdog_device *wdd)
|
||||||
|
{
|
||||||
|
return rave_sp_wdt_configure(wdd, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rave_sp_wdt_set_timeout(struct watchdog_device *wdd,
|
||||||
|
unsigned int timeout)
|
||||||
|
{
|
||||||
|
wdd->timeout = timeout;
|
||||||
|
|
||||||
|
return rave_sp_wdt_configure(wdd, watchdog_active(wdd));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rave_sp_wdt_ping(struct watchdog_device *wdd)
|
||||||
|
{
|
||||||
|
u8 cmd[] = {
|
||||||
|
[0] = RAVE_SP_CMD_PET_WDT,
|
||||||
|
[1] = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
return rave_sp_wdt_exec(wdd, cmd, sizeof(cmd));
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct watchdog_info rave_sp_wdt_info = {
|
||||||
|
.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
|
||||||
|
.identity = "RAVE SP Watchdog",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct watchdog_ops rave_sp_wdt_ops = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.start = rave_sp_wdt_start,
|
||||||
|
.stop = rave_sp_wdt_stop,
|
||||||
|
.ping = rave_sp_wdt_ping,
|
||||||
|
.set_timeout = rave_sp_wdt_set_timeout,
|
||||||
|
.restart = rave_sp_wdt_restart,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct rave_sp_wdt_variant rave_sp_wdt_legacy = {
|
||||||
|
.max_timeout = 255,
|
||||||
|
.min_timeout = 1,
|
||||||
|
.configure = rave_sp_wdt_legacy_configure,
|
||||||
|
.restart = rave_sp_wdt_legacy_restart,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct rave_sp_wdt_variant rave_sp_wdt_rdu = {
|
||||||
|
.max_timeout = 180,
|
||||||
|
.min_timeout = 60,
|
||||||
|
.configure = rave_sp_wdt_rdu_configure,
|
||||||
|
.restart = rave_sp_wdt_rdu_restart,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct of_device_id rave_sp_wdt_of_match[] = {
|
||||||
|
{
|
||||||
|
.compatible = "zii,rave-sp-watchdog-legacy",
|
||||||
|
.data = &rave_sp_wdt_legacy,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.compatible = "zii,rave-sp-watchdog",
|
||||||
|
.data = &rave_sp_wdt_rdu,
|
||||||
|
},
|
||||||
|
{ /* sentinel */ }
|
||||||
|
};
|
||||||
|
|
||||||
|
static int rave_sp_wdt_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct device *dev = &pdev->dev;
|
||||||
|
struct watchdog_device *wdd;
|
||||||
|
struct rave_sp_wdt *sp_wd;
|
||||||
|
struct nvmem_cell *cell;
|
||||||
|
__le16 timeout = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
sp_wd = devm_kzalloc(dev, sizeof(*sp_wd), GFP_KERNEL);
|
||||||
|
if (!sp_wd)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
sp_wd->variant = of_device_get_match_data(dev);
|
||||||
|
sp_wd->sp = dev_get_drvdata(dev->parent);
|
||||||
|
|
||||||
|
wdd = &sp_wd->wdd;
|
||||||
|
wdd->parent = dev;
|
||||||
|
wdd->info = &rave_sp_wdt_info;
|
||||||
|
wdd->ops = &rave_sp_wdt_ops;
|
||||||
|
wdd->min_timeout = sp_wd->variant->min_timeout;
|
||||||
|
wdd->max_timeout = sp_wd->variant->max_timeout;
|
||||||
|
wdd->status = WATCHDOG_NOWAYOUT_INIT_STATUS;
|
||||||
|
wdd->timeout = 60;
|
||||||
|
|
||||||
|
cell = nvmem_cell_get(dev, "wdt-timeout");
|
||||||
|
if (!IS_ERR(cell)) {
|
||||||
|
size_t len;
|
||||||
|
void *value = nvmem_cell_read(cell, &len);
|
||||||
|
|
||||||
|
if (!IS_ERR(value)) {
|
||||||
|
memcpy(&timeout, value, min(len, sizeof(timeout)));
|
||||||
|
kfree(value);
|
||||||
|
}
|
||||||
|
nvmem_cell_put(cell);
|
||||||
|
}
|
||||||
|
watchdog_init_timeout(wdd, le16_to_cpu(timeout), dev);
|
||||||
|
watchdog_set_restart_priority(wdd, 255);
|
||||||
|
watchdog_stop_on_unregister(wdd);
|
||||||
|
|
||||||
|
sp_wd->reboot_notifier.notifier_call = rave_sp_wdt_reboot_notifier;
|
||||||
|
ret = devm_register_reboot_notifier(dev, &sp_wd->reboot_notifier);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(dev, "Failed to register reboot notifier\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We don't know if watchdog is running now. To be sure, let's
|
||||||
|
* start it and depend on watchdog core to ping it
|
||||||
|
*/
|
||||||
|
wdd->max_hw_heartbeat_ms = wdd->max_timeout * 1000;
|
||||||
|
ret = rave_sp_wdt_start(wdd);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(dev, "Watchdog didn't start\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = devm_watchdog_register_device(dev, wdd);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(dev, "Failed to register watchdog device\n");
|
||||||
|
rave_sp_wdt_stop(wdd);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct platform_driver rave_sp_wdt_driver = {
|
||||||
|
.probe = rave_sp_wdt_probe,
|
||||||
|
.driver = {
|
||||||
|
.name = KBUILD_MODNAME,
|
||||||
|
.of_match_table = rave_sp_wdt_of_match,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
module_platform_driver(rave_sp_wdt_driver);
|
||||||
|
|
||||||
|
MODULE_DEVICE_TABLE(of, rave_sp_wdt_of_match);
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_AUTHOR("Andrey Vostrikov <andrey.vostrikov@cogentembedded.com>");
|
||||||
|
MODULE_AUTHOR("Nikita Yushchenko <nikita.yoush@cogentembedded.com>");
|
||||||
|
MODULE_AUTHOR("Andrey Smirnov <andrew.smirnov@gmail.com>");
|
||||||
|
MODULE_DESCRIPTION("RAVE SP Watchdog driver");
|
||||||
|
MODULE_ALIAS("platform:rave-sp-watchdog");
|
|
@ -5,12 +5,19 @@
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
extern u16 const crc_ccitt_table[256];
|
extern u16 const crc_ccitt_table[256];
|
||||||
|
extern u16 const crc_ccitt_false_table[256];
|
||||||
|
|
||||||
extern u16 crc_ccitt(u16 crc, const u8 *buffer, size_t len);
|
extern u16 crc_ccitt(u16 crc, const u8 *buffer, size_t len);
|
||||||
|
extern u16 crc_ccitt_false(u16 crc, const u8 *buffer, size_t len);
|
||||||
|
|
||||||
static inline u16 crc_ccitt_byte(u16 crc, const u8 c)
|
static inline u16 crc_ccitt_byte(u16 crc, const u8 c)
|
||||||
{
|
{
|
||||||
return (crc >> 8) ^ crc_ccitt_table[(crc ^ c) & 0xff];
|
return (crc >> 8) ^ crc_ccitt_table[(crc ^ c) & 0xff];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline u16 crc_ccitt_false_byte(u16 crc, const u8 c)
|
||||||
|
{
|
||||||
|
return (crc << 8) ^ crc_ccitt_false_table[(crc >> 8) ^ c];
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* _LINUX_CRC_CCITT_H */
|
#endif /* _LINUX_CRC_CCITT_H */
|
||||||
|
|
|
@ -645,11 +645,6 @@ struct axp20x_dev {
|
||||||
const struct regmap_irq_chip *regmap_irq_chip;
|
const struct regmap_irq_chip *regmap_irq_chip;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct axp288_extcon_pdata {
|
|
||||||
/* GPIO pin control to switch D+/D- lines b/w PMIC and SOC */
|
|
||||||
struct gpio_desc *gpio_mux_cntl;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* generic helper function for reading 9-16 bit wide regs */
|
/* generic helper function for reading 9-16 bit wide regs */
|
||||||
static inline int axp20x_read_variable_width(struct regmap *regmap,
|
static inline int axp20x_read_variable_width(struct regmap *regmap,
|
||||||
unsigned int reg, unsigned int width)
|
unsigned int reg, unsigned int width)
|
||||||
|
|
|
@ -322,6 +322,10 @@ extern struct attribute_group cros_ec_attr_group;
|
||||||
extern struct attribute_group cros_ec_lightbar_attr_group;
|
extern struct attribute_group cros_ec_lightbar_attr_group;
|
||||||
extern struct attribute_group cros_ec_vbc_attr_group;
|
extern struct attribute_group cros_ec_vbc_attr_group;
|
||||||
|
|
||||||
|
/* debugfs stuff */
|
||||||
|
int cros_ec_debugfs_init(struct cros_ec_dev *ec);
|
||||||
|
void cros_ec_debugfs_remove(struct cros_ec_dev *ec);
|
||||||
|
|
||||||
/* ACPI GPE handler */
|
/* ACPI GPE handler */
|
||||||
#ifdef CONFIG_ACPI
|
#ifdef CONFIG_ACPI
|
||||||
|
|
||||||
|
|
|
@ -2904,16 +2904,33 @@ enum usb_pd_control_mux {
|
||||||
USB_PD_CTRL_MUX_AUTO = 5,
|
USB_PD_CTRL_MUX_AUTO = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum usb_pd_control_swap {
|
||||||
|
USB_PD_CTRL_SWAP_NONE = 0,
|
||||||
|
USB_PD_CTRL_SWAP_DATA = 1,
|
||||||
|
USB_PD_CTRL_SWAP_POWER = 2,
|
||||||
|
USB_PD_CTRL_SWAP_VCONN = 3,
|
||||||
|
USB_PD_CTRL_SWAP_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
struct ec_params_usb_pd_control {
|
struct ec_params_usb_pd_control {
|
||||||
uint8_t port;
|
uint8_t port;
|
||||||
uint8_t role;
|
uint8_t role;
|
||||||
uint8_t mux;
|
uint8_t mux;
|
||||||
|
uint8_t swap;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
#define PD_CTRL_RESP_ENABLED_COMMS (1 << 0) /* Communication enabled */
|
#define PD_CTRL_RESP_ENABLED_COMMS (1 << 0) /* Communication enabled */
|
||||||
#define PD_CTRL_RESP_ENABLED_CONNECTED (1 << 1) /* Device connected */
|
#define PD_CTRL_RESP_ENABLED_CONNECTED (1 << 1) /* Device connected */
|
||||||
#define PD_CTRL_RESP_ENABLED_PD_CAPABLE (1 << 2) /* Partner is PD capable */
|
#define PD_CTRL_RESP_ENABLED_PD_CAPABLE (1 << 2) /* Partner is PD capable */
|
||||||
|
|
||||||
|
#define PD_CTRL_RESP_ROLE_POWER BIT(0) /* 0=SNK/1=SRC */
|
||||||
|
#define PD_CTRL_RESP_ROLE_DATA BIT(1) /* 0=UFP/1=DFP */
|
||||||
|
#define PD_CTRL_RESP_ROLE_VCONN BIT(2) /* Vconn status */
|
||||||
|
#define PD_CTRL_RESP_ROLE_DR_POWER BIT(3) /* Partner is dualrole power */
|
||||||
|
#define PD_CTRL_RESP_ROLE_DR_DATA BIT(4) /* Partner is dualrole data */
|
||||||
|
#define PD_CTRL_RESP_ROLE_USB_COMM BIT(5) /* Partner USB comm capable */
|
||||||
|
#define PD_CTRL_RESP_ROLE_EXT_POWERED BIT(6) /* Partner externally powerd */
|
||||||
|
|
||||||
struct ec_response_usb_pd_control_v1 {
|
struct ec_response_usb_pd_control_v1 {
|
||||||
uint8_t enabled;
|
uint8_t enabled;
|
||||||
uint8_t role;
|
uint8_t role;
|
||||||
|
|
|
@ -3733,6 +3733,9 @@ enum usb_irq_events {
|
||||||
#define TPS65917_REGEN3_CTRL_MODE_ACTIVE 0x01
|
#define TPS65917_REGEN3_CTRL_MODE_ACTIVE 0x01
|
||||||
#define TPS65917_REGEN3_CTRL_MODE_ACTIVE_SHIFT 0x00
|
#define TPS65917_REGEN3_CTRL_MODE_ACTIVE_SHIFT 0x00
|
||||||
|
|
||||||
|
/* POWERHOLD Mask field for PRIMARY_SECONDARY_PAD2 register */
|
||||||
|
#define TPS65917_PRIMARY_SECONDARY_PAD2_GPIO_5_MASK 0xC
|
||||||
|
|
||||||
/* Registers for function RESOURCE */
|
/* Registers for function RESOURCE */
|
||||||
#define TPS65917_REGEN1_CTRL 0x2
|
#define TPS65917_REGEN1_CTRL 0x2
|
||||||
#define TPS65917_PLLEN_CTRL 0x3
|
#define TPS65917_PLLEN_CTRL 0x3
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Core definitions for RAVE SP MFD driver.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 Zodiac Inflight Innovations
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _LINUX_RAVE_SP_H_
|
||||||
|
#define _LINUX_RAVE_SP_H_
|
||||||
|
|
||||||
|
#include <linux/notifier.h>
|
||||||
|
|
||||||
|
enum rave_sp_command {
|
||||||
|
RAVE_SP_CMD_GET_FIRMWARE_VERSION = 0x20,
|
||||||
|
RAVE_SP_CMD_GET_BOOTLOADER_VERSION = 0x21,
|
||||||
|
RAVE_SP_CMD_BOOT_SOURCE = 0x26,
|
||||||
|
RAVE_SP_CMD_GET_BOARD_COPPER_REV = 0x2B,
|
||||||
|
RAVE_SP_CMD_GET_GPIO_STATE = 0x2F,
|
||||||
|
|
||||||
|
RAVE_SP_CMD_STATUS = 0xA0,
|
||||||
|
RAVE_SP_CMD_SW_WDT = 0xA1,
|
||||||
|
RAVE_SP_CMD_PET_WDT = 0xA2,
|
||||||
|
RAVE_SP_CMD_RESET = 0xA7,
|
||||||
|
RAVE_SP_CMD_RESET_REASON = 0xA8,
|
||||||
|
|
||||||
|
RAVE_SP_CMD_REQ_COPPER_REV = 0xB6,
|
||||||
|
RAVE_SP_CMD_GET_I2C_DEVICE_STATUS = 0xBA,
|
||||||
|
RAVE_SP_CMD_GET_SP_SILICON_REV = 0xB9,
|
||||||
|
RAVE_SP_CMD_CONTROL_EVENTS = 0xBB,
|
||||||
|
|
||||||
|
RAVE_SP_EVNT_BASE = 0xE0,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rave_sp;
|
||||||
|
|
||||||
|
static inline unsigned long rave_sp_action_pack(u8 event, u8 value)
|
||||||
|
{
|
||||||
|
return ((unsigned long)value << 8) | event;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u8 rave_sp_action_unpack_event(unsigned long action)
|
||||||
|
{
|
||||||
|
return action;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u8 rave_sp_action_unpack_value(unsigned long action)
|
||||||
|
{
|
||||||
|
return action >> 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rave_sp_exec(struct rave_sp *sp,
|
||||||
|
void *__data, size_t data_size,
|
||||||
|
void *reply_data, size_t reply_data_size);
|
||||||
|
|
||||||
|
struct device;
|
||||||
|
int devm_rave_sp_register_event_notifier(struct device *dev,
|
||||||
|
struct notifier_block *nb);
|
||||||
|
|
||||||
|
#endif /* _LINUX_RAVE_SP_H_ */
|
|
@ -1,13 +1,9 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
/*
|
/*
|
||||||
* STM32 Low-Power Timer parent driver.
|
* STM32 Low-Power Timer parent driver.
|
||||||
*
|
|
||||||
* Copyright (C) STMicroelectronics 2017
|
* Copyright (C) STMicroelectronics 2017
|
||||||
*
|
|
||||||
* Author: Fabrice Gasnier <fabrice.gasnier@st.com>
|
* Author: Fabrice Gasnier <fabrice.gasnier@st.com>
|
||||||
*
|
|
||||||
* Inspired by Benjamin Gaignard's stm32-timers driver
|
* Inspired by Benjamin Gaignard's stm32-timers driver
|
||||||
*
|
|
||||||
* License terms: GNU General Public License (GPL), version 2
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _LINUX_STM32_LPTIMER_H_
|
#ifndef _LINUX_STM32_LPTIMER_H_
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
/*
|
/*
|
||||||
* Copyright (C) STMicroelectronics 2016
|
* Copyright (C) STMicroelectronics 2016
|
||||||
*
|
|
||||||
* Author: Benjamin Gaignard <benjamin.gaignard@st.com>
|
* Author: Benjamin Gaignard <benjamin.gaignard@st.com>
|
||||||
*
|
|
||||||
* License terms: GNU General Public License (GPL), version 2
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _LINUX_STM32_GPTIMER_H_
|
#ifndef _LINUX_STM32_GPTIMER_H_
|
||||||
|
|
|
@ -25,26 +25,6 @@
|
||||||
writew((val) >> 16, (addr) + 2); \
|
writew((val) >> 16, (addr) + 2); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define CNF_CMD 0x04
|
|
||||||
#define CNF_CTL_BASE 0x10
|
|
||||||
#define CNF_INT_PIN 0x3d
|
|
||||||
#define CNF_STOP_CLK_CTL 0x40
|
|
||||||
#define CNF_GCLK_CTL 0x41
|
|
||||||
#define CNF_SD_CLK_MODE 0x42
|
|
||||||
#define CNF_PIN_STATUS 0x44
|
|
||||||
#define CNF_PWR_CTL_1 0x48
|
|
||||||
#define CNF_PWR_CTL_2 0x49
|
|
||||||
#define CNF_PWR_CTL_3 0x4a
|
|
||||||
#define CNF_CARD_DETECT_MODE 0x4c
|
|
||||||
#define CNF_SD_SLOT 0x50
|
|
||||||
#define CNF_EXT_GCLK_CTL_1 0xf0
|
|
||||||
#define CNF_EXT_GCLK_CTL_2 0xf1
|
|
||||||
#define CNF_EXT_GCLK_CTL_3 0xf9
|
|
||||||
#define CNF_SD_LED_EN_1 0xfa
|
|
||||||
#define CNF_SD_LED_EN_2 0xfe
|
|
||||||
|
|
||||||
#define SDCREN 0x2 /* Enable access to MMC CTL regs. (flag in COMMAND_REG)*/
|
|
||||||
|
|
||||||
#define sd_config_write8(base, shift, reg, val) \
|
#define sd_config_write8(base, shift, reg, val) \
|
||||||
tmio_iowrite8((val), (base) + ((reg) << (shift)))
|
tmio_iowrite8((val), (base) + ((reg) << (shift)))
|
||||||
#define sd_config_write16(base, shift, reg, val) \
|
#define sd_config_write16(base, shift, reg, val) \
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <linux/mfd/rtsx_common.h>
|
#include <linux/rtsx_common.h>
|
||||||
|
|
||||||
#define MAX_RW_REG_CNT 1024
|
#define MAX_RW_REG_CNT 1024
|
||||||
|
|
||||||
|
@ -203,6 +203,7 @@
|
||||||
#define SD_DDR_MODE 0x04
|
#define SD_DDR_MODE 0x04
|
||||||
#define SD_30_MODE 0x08
|
#define SD_30_MODE 0x08
|
||||||
#define SD_CLK_DIVIDE_MASK 0xC0
|
#define SD_CLK_DIVIDE_MASK 0xC0
|
||||||
|
#define SD_MODE_SELECT_MASK 0x0C
|
||||||
#define SD_CFG2 0xFDA1
|
#define SD_CFG2 0xFDA1
|
||||||
#define SD_CALCULATE_CRC7 0x00
|
#define SD_CALCULATE_CRC7 0x00
|
||||||
#define SD_NO_CALCULATE_CRC7 0x80
|
#define SD_NO_CALCULATE_CRC7 0x80
|
||||||
|
@ -226,6 +227,7 @@
|
||||||
#define SD_RSP_TYPE_R6 0x01
|
#define SD_RSP_TYPE_R6 0x01
|
||||||
#define SD_RSP_TYPE_R7 0x01
|
#define SD_RSP_TYPE_R7 0x01
|
||||||
#define SD_CFG3 0xFDA2
|
#define SD_CFG3 0xFDA2
|
||||||
|
#define SD30_CLK_END_EN 0x10
|
||||||
#define SD_RSP_80CLK_TIMEOUT_EN 0x01
|
#define SD_RSP_80CLK_TIMEOUT_EN 0x01
|
||||||
|
|
||||||
#define SD_STAT1 0xFDA3
|
#define SD_STAT1 0xFDA3
|
||||||
|
@ -309,6 +311,12 @@
|
||||||
|
|
||||||
#define SD_DATA_STATE 0xFDB6
|
#define SD_DATA_STATE 0xFDB6
|
||||||
#define SD_DATA_IDLE 0x80
|
#define SD_DATA_IDLE 0x80
|
||||||
|
#define REG_SD_STOP_SDCLK_CFG 0xFDB8
|
||||||
|
#define SD30_CLK_STOP_CFG_EN 0x04
|
||||||
|
#define SD30_CLK_STOP_CFG1 0x02
|
||||||
|
#define SD30_CLK_STOP_CFG0 0x01
|
||||||
|
#define REG_PRE_RW_MODE 0xFD70
|
||||||
|
#define EN_INFINITE_MODE 0x01
|
||||||
|
|
||||||
#define SRCTL 0xFC13
|
#define SRCTL 0xFC13
|
||||||
|
|
||||||
|
@ -434,6 +442,7 @@
|
||||||
#define CARD_CLK_EN 0xFD69
|
#define CARD_CLK_EN 0xFD69
|
||||||
#define SD_CLK_EN 0x04
|
#define SD_CLK_EN 0x04
|
||||||
#define MS_CLK_EN 0x08
|
#define MS_CLK_EN 0x08
|
||||||
|
#define SD40_CLK_EN 0x10
|
||||||
#define SDIO_CTRL 0xFD6B
|
#define SDIO_CTRL 0xFD6B
|
||||||
#define CD_PAD_CTL 0xFD73
|
#define CD_PAD_CTL 0xFD73
|
||||||
#define CD_DISABLE_MASK 0x07
|
#define CD_DISABLE_MASK 0x07
|
||||||
|
@ -453,8 +462,8 @@
|
||||||
#define FPDCTL 0xFC00
|
#define FPDCTL 0xFC00
|
||||||
#define SSC_POWER_DOWN 0x01
|
#define SSC_POWER_DOWN 0x01
|
||||||
#define SD_OC_POWER_DOWN 0x02
|
#define SD_OC_POWER_DOWN 0x02
|
||||||
#define ALL_POWER_DOWN 0x07
|
#define ALL_POWER_DOWN 0x03
|
||||||
#define OC_POWER_DOWN 0x06
|
#define OC_POWER_DOWN 0x02
|
||||||
#define PDINFO 0xFC01
|
#define PDINFO 0xFC01
|
||||||
|
|
||||||
#define CLK_CTL 0xFC02
|
#define CLK_CTL 0xFC02
|
||||||
|
@ -490,6 +499,9 @@
|
||||||
|
|
||||||
#define FPGA_PULL_CTL 0xFC1D
|
#define FPGA_PULL_CTL 0xFC1D
|
||||||
#define OLT_LED_CTL 0xFC1E
|
#define OLT_LED_CTL 0xFC1E
|
||||||
|
#define LED_SHINE_MASK 0x08
|
||||||
|
#define LED_SHINE_EN 0x08
|
||||||
|
#define LED_SHINE_DISABLE 0x00
|
||||||
#define GPIO_CTL 0xFC1F
|
#define GPIO_CTL 0xFC1F
|
||||||
|
|
||||||
#define LDO_CTL 0xFC1E
|
#define LDO_CTL 0xFC1E
|
||||||
|
@ -511,7 +523,11 @@
|
||||||
#define BPP_LDO_ON 0x00
|
#define BPP_LDO_ON 0x00
|
||||||
#define BPP_LDO_SUSPEND 0x02
|
#define BPP_LDO_SUSPEND 0x02
|
||||||
#define BPP_LDO_OFF 0x03
|
#define BPP_LDO_OFF 0x03
|
||||||
|
#define EFUSE_CTL 0xFC30
|
||||||
|
#define EFUSE_ADD 0xFC31
|
||||||
#define SYS_VER 0xFC32
|
#define SYS_VER 0xFC32
|
||||||
|
#define EFUSE_DATAL 0xFC34
|
||||||
|
#define EFUSE_DATAH 0xFC35
|
||||||
|
|
||||||
#define CARD_PULL_CTL1 0xFD60
|
#define CARD_PULL_CTL1 0xFD60
|
||||||
#define CARD_PULL_CTL2 0xFD61
|
#define CARD_PULL_CTL2 0xFD61
|
||||||
|
@ -553,6 +569,9 @@
|
||||||
#define RBBC1 0xFE2F
|
#define RBBC1 0xFE2F
|
||||||
#define RBDAT 0xFE30
|
#define RBDAT 0xFE30
|
||||||
#define RBCTL 0xFE34
|
#define RBCTL 0xFE34
|
||||||
|
#define U_AUTO_DMA_EN_MASK 0x20
|
||||||
|
#define U_AUTO_DMA_DISABLE 0x00
|
||||||
|
#define RB_FLUSH 0x80
|
||||||
#define CFGADDR0 0xFE35
|
#define CFGADDR0 0xFE35
|
||||||
#define CFGADDR1 0xFE36
|
#define CFGADDR1 0xFE36
|
||||||
#define CFGDATA0 0xFE37
|
#define CFGDATA0 0xFE37
|
||||||
|
@ -581,6 +600,8 @@
|
||||||
#define LTR_LATENCY_MODE_HW 0
|
#define LTR_LATENCY_MODE_HW 0
|
||||||
#define LTR_LATENCY_MODE_SW BIT(6)
|
#define LTR_LATENCY_MODE_SW BIT(6)
|
||||||
#define OBFF_CFG 0xFE4C
|
#define OBFF_CFG 0xFE4C
|
||||||
|
#define OBFF_EN_MASK 0x03
|
||||||
|
#define OBFF_DISABLE 0x00
|
||||||
|
|
||||||
#define CDRESUMECTL 0xFE52
|
#define CDRESUMECTL 0xFE52
|
||||||
#define WAKE_SEL_CTL 0xFE54
|
#define WAKE_SEL_CTL 0xFE54
|
||||||
|
@ -595,6 +616,7 @@
|
||||||
#define FORCE_ASPM_L0_EN 0x01
|
#define FORCE_ASPM_L0_EN 0x01
|
||||||
#define FORCE_ASPM_NO_ASPM 0x00
|
#define FORCE_ASPM_NO_ASPM 0x00
|
||||||
#define PM_CLK_FORCE_CTL 0xFE58
|
#define PM_CLK_FORCE_CTL 0xFE58
|
||||||
|
#define CLK_PM_EN 0x01
|
||||||
#define FUNC_FORCE_CTL 0xFE59
|
#define FUNC_FORCE_CTL 0xFE59
|
||||||
#define FUNC_FORCE_UPME_XMT_DBG 0x02
|
#define FUNC_FORCE_UPME_XMT_DBG 0x02
|
||||||
#define PERST_GLITCH_WIDTH 0xFE5C
|
#define PERST_GLITCH_WIDTH 0xFE5C
|
||||||
|
@ -620,14 +642,23 @@
|
||||||
#define LDO_PWR_SEL 0xFE78
|
#define LDO_PWR_SEL 0xFE78
|
||||||
|
|
||||||
#define L1SUB_CONFIG1 0xFE8D
|
#define L1SUB_CONFIG1 0xFE8D
|
||||||
|
#define AUX_CLK_ACTIVE_SEL_MASK 0x01
|
||||||
|
#define MAC_CKSW_DONE 0x00
|
||||||
#define L1SUB_CONFIG2 0xFE8E
|
#define L1SUB_CONFIG2 0xFE8E
|
||||||
#define L1SUB_AUTO_CFG 0x02
|
#define L1SUB_AUTO_CFG 0x02
|
||||||
#define L1SUB_CONFIG3 0xFE8F
|
#define L1SUB_CONFIG3 0xFE8F
|
||||||
#define L1OFF_MBIAS2_EN_5250 BIT(7)
|
#define L1OFF_MBIAS2_EN_5250 BIT(7)
|
||||||
|
|
||||||
#define DUMMY_REG_RESET_0 0xFE90
|
#define DUMMY_REG_RESET_0 0xFE90
|
||||||
|
#define IC_VERSION_MASK 0x0F
|
||||||
|
|
||||||
|
#define REG_VREF 0xFE97
|
||||||
|
#define PWD_SUSPND_EN 0x10
|
||||||
|
#define RTS5260_DMA_RST_CTL_0 0xFEBF
|
||||||
|
#define RTS5260_DMA_RST 0x80
|
||||||
|
#define RTS5260_ADMA3_RST 0x40
|
||||||
#define AUTOLOAD_CFG_BASE 0xFF00
|
#define AUTOLOAD_CFG_BASE 0xFF00
|
||||||
|
#define RELINK_TIME_MASK 0x01
|
||||||
#define PETXCFG 0xFF03
|
#define PETXCFG 0xFF03
|
||||||
#define FORCE_CLKREQ_DELINK_MASK BIT(7)
|
#define FORCE_CLKREQ_DELINK_MASK BIT(7)
|
||||||
#define FORCE_CLKREQ_LOW 0x80
|
#define FORCE_CLKREQ_LOW 0x80
|
||||||
|
@ -667,15 +698,24 @@
|
||||||
#define LDO_DV18_CFG 0xFF70
|
#define LDO_DV18_CFG 0xFF70
|
||||||
#define LDO_DV18_SR_MASK 0xC0
|
#define LDO_DV18_SR_MASK 0xC0
|
||||||
#define LDO_DV18_SR_DF 0x40
|
#define LDO_DV18_SR_DF 0x40
|
||||||
|
#define DV331812_MASK 0x70
|
||||||
|
#define DV331812_33 0x70
|
||||||
|
#define DV331812_17 0x30
|
||||||
|
|
||||||
#define LDO_CONFIG2 0xFF71
|
#define LDO_CONFIG2 0xFF71
|
||||||
#define LDO_D3318_MASK 0x07
|
#define LDO_D3318_MASK 0x07
|
||||||
#define LDO_D3318_33V 0x07
|
#define LDO_D3318_33V 0x07
|
||||||
#define LDO_D3318_18V 0x02
|
#define LDO_D3318_18V 0x02
|
||||||
|
#define DV331812_VDD1 0x04
|
||||||
|
#define DV331812_POWERON 0x08
|
||||||
|
#define DV331812_POWEROFF 0x00
|
||||||
|
|
||||||
#define LDO_VCC_CFG0 0xFF72
|
#define LDO_VCC_CFG0 0xFF72
|
||||||
#define LDO_VCC_LMTVTH_MASK 0x30
|
#define LDO_VCC_LMTVTH_MASK 0x30
|
||||||
#define LDO_VCC_LMTVTH_2A 0x10
|
#define LDO_VCC_LMTVTH_2A 0x10
|
||||||
|
/*RTS5260*/
|
||||||
|
#define RTS5260_DVCC_TUNE_MASK 0x70
|
||||||
|
#define RTS5260_DVCC_33 0x70
|
||||||
|
|
||||||
#define LDO_VCC_CFG1 0xFF73
|
#define LDO_VCC_CFG1 0xFF73
|
||||||
#define LDO_VCC_REF_TUNE_MASK 0x30
|
#define LDO_VCC_REF_TUNE_MASK 0x30
|
||||||
|
@ -684,6 +724,10 @@
|
||||||
#define LDO_VCC_1V8 0x04
|
#define LDO_VCC_1V8 0x04
|
||||||
#define LDO_VCC_3V3 0x07
|
#define LDO_VCC_3V3 0x07
|
||||||
#define LDO_VCC_LMT_EN 0x08
|
#define LDO_VCC_LMT_EN 0x08
|
||||||
|
/*RTS5260*/
|
||||||
|
#define LDO_POW_SDVDD1_MASK 0x08
|
||||||
|
#define LDO_POW_SDVDD1_ON 0x08
|
||||||
|
#define LDO_POW_SDVDD1_OFF 0x00
|
||||||
|
|
||||||
#define LDO_VIO_CFG 0xFF75
|
#define LDO_VIO_CFG 0xFF75
|
||||||
#define LDO_VIO_SR_MASK 0xC0
|
#define LDO_VIO_SR_MASK 0xC0
|
||||||
|
@ -711,6 +755,160 @@
|
||||||
#define SD_VIO_LDO_1V8 0x40
|
#define SD_VIO_LDO_1V8 0x40
|
||||||
#define SD_VIO_LDO_3V3 0x70
|
#define SD_VIO_LDO_3V3 0x70
|
||||||
|
|
||||||
|
#define RTS5260_AUTOLOAD_CFG4 0xFF7F
|
||||||
|
#define RTS5260_MIMO_DISABLE 0x8A
|
||||||
|
|
||||||
|
#define RTS5260_REG_GPIO_CTL0 0xFC1A
|
||||||
|
#define RTS5260_REG_GPIO_MASK 0x01
|
||||||
|
#define RTS5260_REG_GPIO_ON 0x01
|
||||||
|
#define RTS5260_REG_GPIO_OFF 0x00
|
||||||
|
|
||||||
|
#define PWR_GLOBAL_CTRL 0xF200
|
||||||
|
#define PCIE_L1_2_EN 0x0C
|
||||||
|
#define PCIE_L1_1_EN 0x0A
|
||||||
|
#define PCIE_L1_0_EN 0x09
|
||||||
|
#define PWR_FE_CTL 0xF201
|
||||||
|
#define PCIE_L1_2_PD_FE_EN 0x0C
|
||||||
|
#define PCIE_L1_1_PD_FE_EN 0x0A
|
||||||
|
#define PCIE_L1_0_PD_FE_EN 0x09
|
||||||
|
#define CFG_PCIE_APHY_OFF_0 0xF204
|
||||||
|
#define CFG_PCIE_APHY_OFF_0_DEFAULT 0xBF
|
||||||
|
#define CFG_PCIE_APHY_OFF_1 0xF205
|
||||||
|
#define CFG_PCIE_APHY_OFF_1_DEFAULT 0xFF
|
||||||
|
#define CFG_PCIE_APHY_OFF_2 0xF206
|
||||||
|
#define CFG_PCIE_APHY_OFF_2_DEFAULT 0x01
|
||||||
|
#define CFG_PCIE_APHY_OFF_3 0xF207
|
||||||
|
#define CFG_PCIE_APHY_OFF_3_DEFAULT 0x00
|
||||||
|
#define CFG_L1_0_PCIE_MAC_RET_VALUE 0xF20C
|
||||||
|
#define CFG_L1_0_PCIE_DPHY_RET_VALUE 0xF20E
|
||||||
|
#define CFG_L1_0_SYS_RET_VALUE 0xF210
|
||||||
|
#define CFG_L1_0_CRC_MISC_RET_VALUE 0xF212
|
||||||
|
#define CFG_L1_0_CRC_SD30_RET_VALUE 0xF214
|
||||||
|
#define CFG_L1_0_CRC_SD40_RET_VALUE 0xF216
|
||||||
|
#define CFG_LP_FPWM_VALUE 0xF219
|
||||||
|
#define CFG_LP_FPWM_VALUE_DEFAULT 0x18
|
||||||
|
#define PWC_CDR 0xF253
|
||||||
|
#define PWC_CDR_DEFAULT 0x03
|
||||||
|
#define CFG_L1_0_RET_VALUE_DEFAULT 0x1B
|
||||||
|
#define CFG_L1_0_CRC_MISC_RET_VALUE_DEFAULT 0x0C
|
||||||
|
|
||||||
|
/* OCPCTL */
|
||||||
|
#define SD_DETECT_EN 0x08
|
||||||
|
#define SD_OCP_INT_EN 0x04
|
||||||
|
#define SD_OCP_INT_CLR 0x02
|
||||||
|
#define SD_OC_CLR 0x01
|
||||||
|
|
||||||
|
#define SDVIO_DETECT_EN (1 << 7)
|
||||||
|
#define SDVIO_OCP_INT_EN (1 << 6)
|
||||||
|
#define SDVIO_OCP_INT_CLR (1 << 5)
|
||||||
|
#define SDVIO_OC_CLR (1 << 4)
|
||||||
|
|
||||||
|
/* OCPSTAT */
|
||||||
|
#define SD_OCP_DETECT 0x08
|
||||||
|
#define SD_OC_NOW 0x04
|
||||||
|
#define SD_OC_EVER 0x02
|
||||||
|
|
||||||
|
#define SDVIO_OC_NOW (1 << 6)
|
||||||
|
#define SDVIO_OC_EVER (1 << 5)
|
||||||
|
|
||||||
|
#define REG_OCPCTL 0xFD6A
|
||||||
|
#define REG_OCPSTAT 0xFD6E
|
||||||
|
#define REG_OCPGLITCH 0xFD6C
|
||||||
|
#define REG_OCPPARA1 0xFD6B
|
||||||
|
#define REG_OCPPARA2 0xFD6D
|
||||||
|
|
||||||
|
/* rts5260 DV3318 OCP-related registers */
|
||||||
|
#define REG_DV3318_OCPCTL 0xFD89
|
||||||
|
#define DV3318_OCP_TIME_MASK 0xF0
|
||||||
|
#define DV3318_DETECT_EN 0x08
|
||||||
|
#define DV3318_OCP_INT_EN 0x04
|
||||||
|
#define DV3318_OCP_INT_CLR 0x02
|
||||||
|
#define DV3318_OCP_CLR 0x01
|
||||||
|
|
||||||
|
#define REG_DV3318_OCPSTAT 0xFD8A
|
||||||
|
#define DV3318_OCP_GlITCH_TIME_MASK 0xF0
|
||||||
|
#define DV3318_OCP_DETECT 0x08
|
||||||
|
#define DV3318_OCP_NOW 0x04
|
||||||
|
#define DV3318_OCP_EVER 0x02
|
||||||
|
|
||||||
|
#define SD_OCP_GLITCH_MASK 0x0F
|
||||||
|
|
||||||
|
/* OCPPARA1 */
|
||||||
|
#define SDVIO_OCP_TIME_60 0x00
|
||||||
|
#define SDVIO_OCP_TIME_100 0x10
|
||||||
|
#define SDVIO_OCP_TIME_200 0x20
|
||||||
|
#define SDVIO_OCP_TIME_400 0x30
|
||||||
|
#define SDVIO_OCP_TIME_600 0x40
|
||||||
|
#define SDVIO_OCP_TIME_800 0x50
|
||||||
|
#define SDVIO_OCP_TIME_1100 0x60
|
||||||
|
#define SDVIO_OCP_TIME_MASK 0x70
|
||||||
|
|
||||||
|
#define SD_OCP_TIME_60 0x00
|
||||||
|
#define SD_OCP_TIME_100 0x01
|
||||||
|
#define SD_OCP_TIME_200 0x02
|
||||||
|
#define SD_OCP_TIME_400 0x03
|
||||||
|
#define SD_OCP_TIME_600 0x04
|
||||||
|
#define SD_OCP_TIME_800 0x05
|
||||||
|
#define SD_OCP_TIME_1100 0x06
|
||||||
|
#define SD_OCP_TIME_MASK 0x07
|
||||||
|
|
||||||
|
/* OCPPARA2 */
|
||||||
|
#define SDVIO_OCP_THD_190 0x00
|
||||||
|
#define SDVIO_OCP_THD_250 0x10
|
||||||
|
#define SDVIO_OCP_THD_320 0x20
|
||||||
|
#define SDVIO_OCP_THD_380 0x30
|
||||||
|
#define SDVIO_OCP_THD_440 0x40
|
||||||
|
#define SDVIO_OCP_THD_500 0x50
|
||||||
|
#define SDVIO_OCP_THD_570 0x60
|
||||||
|
#define SDVIO_OCP_THD_630 0x70
|
||||||
|
#define SDVIO_OCP_THD_MASK 0x70
|
||||||
|
|
||||||
|
#define SD_OCP_THD_450 0x00
|
||||||
|
#define SD_OCP_THD_550 0x01
|
||||||
|
#define SD_OCP_THD_650 0x02
|
||||||
|
#define SD_OCP_THD_750 0x03
|
||||||
|
#define SD_OCP_THD_850 0x04
|
||||||
|
#define SD_OCP_THD_950 0x05
|
||||||
|
#define SD_OCP_THD_1050 0x06
|
||||||
|
#define SD_OCP_THD_1150 0x07
|
||||||
|
#define SD_OCP_THD_MASK 0x07
|
||||||
|
|
||||||
|
#define SDVIO_OCP_GLITCH_MASK 0xF0
|
||||||
|
#define SDVIO_OCP_GLITCH_NONE 0x00
|
||||||
|
#define SDVIO_OCP_GLITCH_50U 0x10
|
||||||
|
#define SDVIO_OCP_GLITCH_100U 0x20
|
||||||
|
#define SDVIO_OCP_GLITCH_200U 0x30
|
||||||
|
#define SDVIO_OCP_GLITCH_600U 0x40
|
||||||
|
#define SDVIO_OCP_GLITCH_800U 0x50
|
||||||
|
#define SDVIO_OCP_GLITCH_1M 0x60
|
||||||
|
#define SDVIO_OCP_GLITCH_2M 0x70
|
||||||
|
#define SDVIO_OCP_GLITCH_3M 0x80
|
||||||
|
#define SDVIO_OCP_GLITCH_4M 0x90
|
||||||
|
#define SDVIO_OCP_GLIVCH_5M 0xA0
|
||||||
|
#define SDVIO_OCP_GLITCH_6M 0xB0
|
||||||
|
#define SDVIO_OCP_GLITCH_7M 0xC0
|
||||||
|
#define SDVIO_OCP_GLITCH_8M 0xD0
|
||||||
|
#define SDVIO_OCP_GLITCH_9M 0xE0
|
||||||
|
#define SDVIO_OCP_GLITCH_10M 0xF0
|
||||||
|
|
||||||
|
#define SD_OCP_GLITCH_MASK 0x0F
|
||||||
|
#define SD_OCP_GLITCH_NONE 0x00
|
||||||
|
#define SD_OCP_GLITCH_50U 0x01
|
||||||
|
#define SD_OCP_GLITCH_100U 0x02
|
||||||
|
#define SD_OCP_GLITCH_200U 0x03
|
||||||
|
#define SD_OCP_GLITCH_600U 0x04
|
||||||
|
#define SD_OCP_GLITCH_800U 0x05
|
||||||
|
#define SD_OCP_GLITCH_1M 0x06
|
||||||
|
#define SD_OCP_GLITCH_2M 0x07
|
||||||
|
#define SD_OCP_GLITCH_3M 0x08
|
||||||
|
#define SD_OCP_GLITCH_4M 0x09
|
||||||
|
#define SD_OCP_GLIVCH_5M 0x0A
|
||||||
|
#define SD_OCP_GLITCH_6M 0x0B
|
||||||
|
#define SD_OCP_GLITCH_7M 0x0C
|
||||||
|
#define SD_OCP_GLITCH_8M 0x0D
|
||||||
|
#define SD_OCP_GLITCH_9M 0x0E
|
||||||
|
#define SD_OCP_GLITCH_10M 0x0F
|
||||||
|
|
||||||
/* Phy register */
|
/* Phy register */
|
||||||
#define PHY_PCR 0x00
|
#define PHY_PCR 0x00
|
||||||
#define PHY_PCR_FORCE_CODE 0xB000
|
#define PHY_PCR_FORCE_CODE 0xB000
|
||||||
|
@ -857,6 +1055,7 @@
|
||||||
|
|
||||||
#define PCR_ASPM_SETTING_REG1 0x160
|
#define PCR_ASPM_SETTING_REG1 0x160
|
||||||
#define PCR_ASPM_SETTING_REG2 0x168
|
#define PCR_ASPM_SETTING_REG2 0x168
|
||||||
|
#define PCR_ASPM_SETTING_5260 0x178
|
||||||
|
|
||||||
#define PCR_SETTING_REG1 0x724
|
#define PCR_SETTING_REG1 0x724
|
||||||
#define PCR_SETTING_REG2 0x814
|
#define PCR_SETTING_REG2 0x814
|
||||||
|
@ -890,6 +1089,7 @@ struct pcr_ops {
|
||||||
int (*conv_clk_and_div_n)(int clk, int dir);
|
int (*conv_clk_and_div_n)(int clk, int dir);
|
||||||
void (*fetch_vendor_settings)(struct rtsx_pcr *pcr);
|
void (*fetch_vendor_settings)(struct rtsx_pcr *pcr);
|
||||||
void (*force_power_down)(struct rtsx_pcr *pcr, u8 pm_state);
|
void (*force_power_down)(struct rtsx_pcr *pcr, u8 pm_state);
|
||||||
|
void (*stop_cmd)(struct rtsx_pcr *pcr);
|
||||||
|
|
||||||
void (*set_aspm)(struct rtsx_pcr *pcr, bool enable);
|
void (*set_aspm)(struct rtsx_pcr *pcr, bool enable);
|
||||||
int (*set_ltr_latency)(struct rtsx_pcr *pcr, u32 latency);
|
int (*set_ltr_latency)(struct rtsx_pcr *pcr, u32 latency);
|
||||||
|
@ -897,6 +1097,12 @@ struct pcr_ops {
|
||||||
void (*set_l1off_cfg_sub_d0)(struct rtsx_pcr *pcr, int active);
|
void (*set_l1off_cfg_sub_d0)(struct rtsx_pcr *pcr, int active);
|
||||||
void (*full_on)(struct rtsx_pcr *pcr);
|
void (*full_on)(struct rtsx_pcr *pcr);
|
||||||
void (*power_saving)(struct rtsx_pcr *pcr);
|
void (*power_saving)(struct rtsx_pcr *pcr);
|
||||||
|
void (*enable_ocp)(struct rtsx_pcr *pcr);
|
||||||
|
void (*disable_ocp)(struct rtsx_pcr *pcr);
|
||||||
|
void (*init_ocp)(struct rtsx_pcr *pcr);
|
||||||
|
void (*process_ocp)(struct rtsx_pcr *pcr);
|
||||||
|
int (*get_ocpstat)(struct rtsx_pcr *pcr, u8 *val);
|
||||||
|
void (*clear_ocpstat)(struct rtsx_pcr *pcr);
|
||||||
};
|
};
|
||||||
|
|
||||||
enum PDEV_STAT {PDEV_STAT_IDLE, PDEV_STAT_RUN};
|
enum PDEV_STAT {PDEV_STAT_IDLE, PDEV_STAT_RUN};
|
||||||
|
@ -935,6 +1141,9 @@ enum dev_aspm_mode {
|
||||||
* @l1_snooze_delay: l1 snooze delay
|
* @l1_snooze_delay: l1 snooze delay
|
||||||
* @ltr_l1off_sspwrgate: ltr l1off sspwrgate
|
* @ltr_l1off_sspwrgate: ltr l1off sspwrgate
|
||||||
* @ltr_l1off_snooze_sspwrgate: ltr l1off snooze sspwrgate
|
* @ltr_l1off_snooze_sspwrgate: ltr l1off snooze sspwrgate
|
||||||
|
* @ocp_en: enable ocp flag
|
||||||
|
* @sd_400mA_ocp_thd: 400mA ocp thd
|
||||||
|
* @sd_800mA_ocp_thd: 800mA ocp thd
|
||||||
*/
|
*/
|
||||||
struct rtsx_cr_option {
|
struct rtsx_cr_option {
|
||||||
u32 dev_flags;
|
u32 dev_flags;
|
||||||
|
@ -949,6 +1158,19 @@ struct rtsx_cr_option {
|
||||||
u32 l1_snooze_delay;
|
u32 l1_snooze_delay;
|
||||||
u8 ltr_l1off_sspwrgate;
|
u8 ltr_l1off_sspwrgate;
|
||||||
u8 ltr_l1off_snooze_sspwrgate;
|
u8 ltr_l1off_snooze_sspwrgate;
|
||||||
|
bool ocp_en;
|
||||||
|
u8 sd_400mA_ocp_thd;
|
||||||
|
u8 sd_800mA_ocp_thd;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* struct rtsx_hw_param - card reader hardware param
|
||||||
|
* @interrupt_en: indicate which interrutp enable
|
||||||
|
* @ocp_glitch: ocp glitch time
|
||||||
|
*/
|
||||||
|
struct rtsx_hw_param {
|
||||||
|
u32 interrupt_en;
|
||||||
|
u8 ocp_glitch;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define rtsx_set_dev_flag(cr, flag) \
|
#define rtsx_set_dev_flag(cr, flag) \
|
||||||
|
@ -963,6 +1185,7 @@ struct rtsx_pcr {
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
int pcie_cap;
|
int pcie_cap;
|
||||||
struct rtsx_cr_option option;
|
struct rtsx_cr_option option;
|
||||||
|
struct rtsx_hw_param hw_param;
|
||||||
|
|
||||||
/* pci resources */
|
/* pci resources */
|
||||||
unsigned long addr;
|
unsigned long addr;
|
||||||
|
@ -1042,12 +1265,15 @@ struct rtsx_pcr {
|
||||||
struct rtsx_slot *slots;
|
struct rtsx_slot *slots;
|
||||||
|
|
||||||
u8 dma_error_count;
|
u8 dma_error_count;
|
||||||
|
u8 ocp_stat;
|
||||||
|
u8 ocp_stat2;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PID_524A 0x524A
|
#define PID_524A 0x524A
|
||||||
#define PID_5249 0x5249
|
#define PID_5249 0x5249
|
||||||
#define PID_5250 0x5250
|
#define PID_5250 0x5250
|
||||||
#define PID_525A 0x525A
|
#define PID_525A 0x525A
|
||||||
|
#define PID_5260 0x5260
|
||||||
|
|
||||||
#define CHK_PCI_PID(pcr, pid) ((pcr)->pci->device == (pid))
|
#define CHK_PCI_PID(pcr, pid) ((pcr)->pci->device == (pid))
|
||||||
#define PCI_VID(pcr) ((pcr)->pci->vendor)
|
#define PCI_VID(pcr) ((pcr)->pci->vendor)
|
|
@ -193,6 +193,7 @@ static inline int serdev_controller_receive_buf(struct serdev_controller *ctrl,
|
||||||
|
|
||||||
int serdev_device_open(struct serdev_device *);
|
int serdev_device_open(struct serdev_device *);
|
||||||
void serdev_device_close(struct serdev_device *);
|
void serdev_device_close(struct serdev_device *);
|
||||||
|
int devm_serdev_device_open(struct device *, struct serdev_device *);
|
||||||
unsigned int serdev_device_set_baudrate(struct serdev_device *, unsigned int);
|
unsigned int serdev_device_set_baudrate(struct serdev_device *, unsigned int);
|
||||||
void serdev_device_set_flow_control(struct serdev_device *, bool);
|
void serdev_device_set_flow_control(struct serdev_device *, bool);
|
||||||
int serdev_device_write_buf(struct serdev_device *, const unsigned char *, size_t);
|
int serdev_device_write_buf(struct serdev_device *, const unsigned char *, size_t);
|
||||||
|
|
|
@ -51,8 +51,49 @@ u16 const crc_ccitt_table[256] = {
|
||||||
};
|
};
|
||||||
EXPORT_SYMBOL(crc_ccitt_table);
|
EXPORT_SYMBOL(crc_ccitt_table);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Similar table to calculate CRC16 variant known as CRC-CCITT-FALSE
|
||||||
|
* Reflected bits order, does not augment final value.
|
||||||
|
*/
|
||||||
|
u16 const crc_ccitt_false_table[256] = {
|
||||||
|
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
|
||||||
|
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
|
||||||
|
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
|
||||||
|
0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
|
||||||
|
0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
|
||||||
|
0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
|
||||||
|
0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
|
||||||
|
0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
|
||||||
|
0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
|
||||||
|
0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
|
||||||
|
0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
|
||||||
|
0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
|
||||||
|
0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
|
||||||
|
0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
|
||||||
|
0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
|
||||||
|
0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
|
||||||
|
0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
|
||||||
|
0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
|
||||||
|
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
|
||||||
|
0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
|
||||||
|
0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
|
||||||
|
0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
|
||||||
|
0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
|
||||||
|
0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
|
||||||
|
0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
|
||||||
|
0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
|
||||||
|
0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
|
||||||
|
0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
|
||||||
|
0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
|
||||||
|
0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
|
||||||
|
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
|
||||||
|
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
|
||||||
|
};
|
||||||
|
EXPORT_SYMBOL(crc_ccitt_false_table);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* crc_ccitt - recompute the CRC for the data buffer
|
* crc_ccitt - recompute the CRC (CRC-CCITT variant) for the data
|
||||||
|
* buffer
|
||||||
* @crc: previous CRC value
|
* @crc: previous CRC value
|
||||||
* @buffer: data pointer
|
* @buffer: data pointer
|
||||||
* @len: number of bytes in the buffer
|
* @len: number of bytes in the buffer
|
||||||
|
@ -65,5 +106,20 @@ u16 crc_ccitt(u16 crc, u8 const *buffer, size_t len)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(crc_ccitt);
|
EXPORT_SYMBOL(crc_ccitt);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* crc_ccitt_false - recompute the CRC (CRC-CCITT-FALSE variant)
|
||||||
|
* for the data buffer
|
||||||
|
* @crc: previous CRC value
|
||||||
|
* @buffer: data pointer
|
||||||
|
* @len: number of bytes in the buffer
|
||||||
|
*/
|
||||||
|
u16 crc_ccitt_false(u16 crc, u8 const *buffer, size_t len)
|
||||||
|
{
|
||||||
|
while (len--)
|
||||||
|
crc = crc_ccitt_false_byte(crc, *buffer++);
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(crc_ccitt_false);
|
||||||
|
|
||||||
MODULE_DESCRIPTION("CRC-CCITT calculations");
|
MODULE_DESCRIPTION("CRC-CCITT calculations");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
Loading…
Reference in New Issue