Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2e57d567 authored by Haojian Zhuang's avatar Haojian Zhuang Committed by Samuel Ortiz
Browse files

mfd: 88pm860x: Device tree support

parent 837c8293
Loading
Loading
Loading
Loading
+85 −0
Original line number Diff line number Diff line
* Marvell 88PM860x Power Management IC

Required parent device properties:
- compatible : "marvell,88pm860x"
- reg : the I2C slave address for the 88pm860x chip
- interrupts : IRQ line for the 88pm860x chip
- interrupt-controller: describes the 88pm860x as an interrupt controller (has its own domain)
- #interrupt-cells : should be 1.
		- The cell is the 88pm860x local IRQ number

Optional parent device properties:
- marvell,88pm860x-irq-read-clr: inicates whether interrupt status is cleared by read
- marvell,88pm860x-slave-addr: 88pm860x are two chips solution. <reg> stores the I2C address
				of one chip, and this property stores the I2C address of
				another chip.

88pm860x consists of a large and varied group of sub-devices:

Device			 Supply Names	 Description
------			 ------------	 -----------
88pm860x-onkey		:		: On key
88pm860x-rtc		:		: RTC
88pm8607		:		: Regulators
88pm860x-backlight	:		: Backlight
88pm860x-led		:		: Led
88pm860x-touch		:		: Touchscreen

Example:

	pmic: 88pm860x@34 {
		compatible = "marvell,88pm860x";
		reg = <0x34>;
		interrupts = <4>;
		interrupt-parent = <&intc>;
		interrupt-controller;
		#interrupt-cells = <1>;

		marvell,88pm860x-irq-read-clr;
		marvell,88pm860x-slave-addr = <0x11>;

		regulators {
			BUCK1 {
				regulator-min-microvolt = <1000000>;
				regulator-max-microvolt = <1500000>;
				regulator-boot-on;
				regulator-always-on;
			};
			LDO1 {
				regulator-min-microvolt = <1200000>;
				regulator-max-microvolt = <2800000>;
				regulator-boot-on;
				regulator-always-on;
			};
		};
		rtc {
			marvell,88pm860x-vrtc = <1>;
		};
		touch {
			marvell,88pm860x-gpadc-prebias = <1>;
			marvell,88pm860x-gpadc-slot-cycle = <1>;
			marvell,88pm860x-tsi-prebias = <6>;
			marvell,88pm860x-pen-prebias = <16>;
			marvell,88pm860x-pen-prechg = <2>;
			marvell,88pm860x-resistor-X = <300>;
		};
		backlights {
			backlight-0 {
				marvell,88pm860x-iset = <4>;
				marvell,88pm860x-pwm = <3>;
			};
			backlight-2 {
			};
		};
		leds {
			led0-red {
				marvell,88pm860x-iset = <12>;
			};
			led0-green {
				marvell,88pm860x-iset = <12>;
			};
			led0-blue {
				marvell,88pm860x-iset = <12>;
			};
		};
	};
+30 −0
Original line number Diff line number Diff line
Marvell 88PM860x regulator

Required properties:
- compatible: "marvell,88pm860x"
- reg: I2C slave address
- regulators: A node that houses a sub-node for each regulator within the
  device. Each sub-node is identified using the regulator-compatible
  property, with valid values listed below.

Example:

	pmic: 88pm860x@34 {
		compatible = "marvell,88pm860x";
		reg = <0x34>;

		regulators {
			BUCK1 {
			        regulator-min-microvolt = <1000000>;
			        regulator-max-microvolt = <1500000>;
			        regulator-boot-on;
			        regulator-always-on;
			};
			BUCK3 {
			        regulator-min-microvolt = <1000000>;
			        regulator-max-microvolt = <3000000>;
			        regulator-boot-on;
			        regulator-always-on;
			};
		};
	};
+15 −0
Original line number Diff line number Diff line
88pm860x-backlight bindings

Optional properties:
  - marvell,88pm860x-iset: Current supplies on backlight device.
  - marvell,88pm860x-pwm: PWM frequency on backlight device.

Example:

	backlights {
		backlight-0 {
			marvell,88pm860x-iset = <4>;
			marvell,88pm860x-pwm = <3>;
		};
		backlight-2 {
		};
+31 −15
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@
 */
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/input.h>
@@ -113,14 +114,31 @@ static void pm860x_touch_close(struct input_dev *dev)
	pm860x_set_bits(touch->i2c, MEAS_EN3, data, 0);
}

#ifdef CONFIG_OF
static int __devinit pm860x_touch_dt_init(struct platform_device *pdev,
					  int *res_x)
{
	struct device_node *np = pdev->dev.parent->of_node;
	if (!np)
		return -ENODEV;
	np = of_find_node_by_name(np, "touch");
	if (!np) {
		dev_err(&pdev->dev, "Can't find touch node\n");
		return -EINVAL;
	}
	of_property_read_u32(np, "marvell,88pm860x-resistor-X", res_x);
	return 0;
}
#else
#define pm860x_touch_dt_init(x, y)	(-1)
#endif

static int __devinit pm860x_touch_probe(struct platform_device *pdev)
{
	struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
	struct pm860x_platform_data *pm860x_pdata =		\
				pdev->dev.parent->platform_data;
	struct pm860x_touch_pdata *pdata = NULL;
	struct pm860x_touch_pdata *pdata = pdev->dev.platform_data;
	struct pm860x_touch *touch;
	int irq, ret;
	int irq, ret, res_x = 0;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
@@ -128,15 +146,13 @@ static int __devinit pm860x_touch_probe(struct platform_device *pdev)
		return -EINVAL;
	}

	if (!pm860x_pdata) {
		dev_err(&pdev->dev, "platform data is missing\n");
	if (pm860x_touch_dt_init(pdev, &res_x)) {
		if (pdata)
			res_x = pdata->res_x;
		else {
			dev_err(&pdev->dev, "failed to get platform data\n");
			return -EINVAL;
		}

	pdata = pm860x_pdata->touch;
	if (!pdata) {
		dev_err(&pdev->dev, "touchscreen data is missing\n");
		return -EINVAL;
	}

	touch = kzalloc(sizeof(struct pm860x_touch), GFP_KERNEL);
@@ -159,8 +175,8 @@ static int __devinit pm860x_touch_probe(struct platform_device *pdev)
	touch->idev->close = pm860x_touch_close;
	touch->chip = chip;
	touch->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
	touch->irq = irq + chip->irq_base;
	touch->res_x = pdata->res_x;
	touch->irq = irq;
	touch->res_x = res_x;
	input_set_drvdata(touch->idev, touch);

	ret = request_threaded_irq(touch->irq, NULL, pm860x_touch_handler,
+31 −2
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/leds.h>
@@ -123,6 +124,33 @@ static void pm860x_led_set(struct led_classdev *cdev,
	schedule_work(&data->work);
}

#ifdef CONFIG_OF
static int pm860x_led_dt_init(struct platform_device *pdev,
			      struct pm860x_led *data)
{
	struct device_node *nproot = pdev->dev.parent->of_node, *np;
	int iset = 0;
	if (!nproot)
		return -ENODEV;
	nproot = of_find_node_by_name(nproot, "leds");
	if (!nproot) {
		dev_err(&pdev->dev, "failed to find leds node\n");
		return -ENODEV;
	}
	for_each_child_of_node(nproot, np) {
		if (!of_node_cmp(np->name, data->name)) {
			of_property_read_u32(np, "marvell,88pm860x-iset",
					     &iset);
			data->iset = PM8606_LED_CURRENT(iset);
			break;
		}
	}
	return 0;
}
#else
#define pm860x_led_dt_init(x, y)	(-1)
#endif

static int pm860x_led_probe(struct platform_device *pdev)
{
	struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
@@ -179,7 +207,8 @@ static int pm860x_led_probe(struct platform_device *pdev)
	data->chip = chip;
	data->i2c = (chip->id == CHIP_PM8606) ? chip->client : chip->companion;
	data->port = pdev->id;
	if (pdata && pdata->iset)
	if (pm860x_led_dt_init(pdev, data))
		if (pdata)
			data->iset = pdata->iset;

	data->current_brightness = 0;
Loading