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

Commit d0f04659 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "vxr7200: add sysfs node for proximity control"

parents 200e541f 244c9ad7
Loading
Loading
Loading
Loading
+179 −116
Original line number Diff line number Diff line
@@ -29,6 +29,12 @@
#include <linux/regulator/consumer.h>
#include <linux/rwlock.h>
#include <linux/leds.h>
#include "vxr7200.h"

enum power_state {
	POWER_STATE_POWERKEY = 0,
	POWER_STATE_ENABLE = 1,
};

struct vxr7200 {
	struct device *dev;
@@ -43,7 +49,6 @@ struct vxr7200 {
	u32 display_1v8_en;
	u32 mipi_switch_1v8_en;
	u32 display_res1;
	bool gpioInit;

	struct i2c_client *i2c_client;

@@ -52,9 +57,13 @@ struct vxr7200 {
	struct regulator *ibb;

	bool power_on;
	bool enable;
	bool usb_plugged;
	enum power_state state;
};

static bool dsi_way;
static struct vxr7200 *pdata;

static int vxr7200_read(struct vxr7200 *pdata, u8 *reg, u8 *buf, u32 size)
{
@@ -75,106 +84,122 @@ static int vxr7200_read(struct vxr7200 *pdata, u8 *reg, u8 *buf, u32 size)
	};

	if (i2c_transfer(client->adapter, msg, 2) != 2) {
		pr_err("i2c read failed\n");
		pr_err("%s i2c read failed\n", __func__);
		return -EIO;
	}

	return 0;
}

static int turnGpio(struct vxr7200 *pdata, int gpio, char *name, bool on)
static void turn_gpio(struct vxr7200 *pdata, int gpio, bool on)
{
	int ret = -1;

	pr_info("%s vxr7200 gpio:%d, name:%s, on:%d\n", __func__, gpio,
						name, on);
	if (!pdata->gpioInit) {
		ret = gpio_request(gpio, name);
		if (ret) {
			pr_err("vxr7200 %s gpio request failed\n", name);
			goto error;
		}
	}
	pr_debug("%s vxr7200_turn_gpio gpio:%d, on:%d\n", __func__, gpio, on);

	if (on) {
		ret = gpio_direction_output(gpio, 0);
		if (ret) {
			pr_err("vxr7200 gpio direction failed\n");
			goto error;
		}
		gpio_direction_output(gpio, 0);
		gpio_set_value(gpio, 1);
		msleep(20);
		pr_debug("%s vxr7200 gpio:%d set to high\n", __func__, gpio);
	} else {
		ret = gpio_direction_output(gpio, 1);
		if (ret) {
			pr_err("vxr7200 gpio direction failed\n");
			goto error;
		}
		gpio_direction_output(gpio, 1);
		gpio_set_value(gpio, 0);
		msleep(20);
		pr_debug("%s vxr7200 gpio:%d set to low\n", __func__, gpio);
	}
	return 0;
error:
	return -EINVAL;
}

static void vxr7200_set_gpios(struct vxr7200 *pdata, bool turnOn)
static void vxr7200_set_gpios(struct vxr7200 *pdata, bool turn_on)
{
	int rc;

	pr_debug("%s, turnOn:%d\n", __func__, turnOn);
	pr_debug("%s, turn_on:%d\n", __func__, turn_on);
	if (pdata) {
		rc = turnGpio(pdata, pdata->vxr_3v3_en, "vxr_3v3_en", turnOn);
		if (rc)
			goto gpio1Fail;
		if (pdata->state == POWER_STATE_POWERKEY) {
			turn_gpio(pdata, pdata->vxr_3v3_en, turn_on);
			turn_gpio(pdata, pdata->display_res1, turn_on);
			turn_gpio(pdata, pdata->display_1v8_en, turn_on);
			turn_gpio(pdata, pdata->mipi_switch_1v8_en, turn_on);
			if (!pdata->enable && turn_on)
				return;
		}
		turn_gpio(pdata, pdata->led_5v_en, turn_on);
		turn_gpio(pdata, pdata->led_drive_en1, turn_on);
		turn_gpio(pdata, pdata->led_drive_en2, turn_on);
	}
	return;
}

		rc = turnGpio(pdata, pdata->display_res1,
						 "display_res1", turnOn);
		if (rc)
			goto gpio2Fail;
static ssize_t vxr7200_enable_show(struct device *dev,
				 struct device_attribute *attr,
				char *buf)
{
	int ret;
	struct i2c_client *client = to_i2c_client(dev);
	struct vxr7200 *pdata = i2c_get_clientdata(client);

		rc = turnGpio(pdata, pdata->display_1v8_en,
					 "disp_1v8_en", turnOn);
		if (rc)
			goto gpio3Fail;

		rc = turnGpio(pdata, pdata->mipi_switch_1v8_en,
						 "mipi_switch_1v8_en", turnOn);
		if (rc)
			goto gpio4Fail;
	if (pdata->enable)
		ret = scnprintf(buf, PAGE_SIZE, "display on\n");
	else
		ret = scnprintf(buf, PAGE_SIZE, "display off\n");

		rc = turnGpio(pdata, pdata->led_5v_en, "led_5v_en", turnOn);
		if (rc)
			goto gpio5Fail;
	return ret;
}

		rc = turnGpio(pdata, pdata->led_drive_en1,
					"led_drive_en1", turnOn);
		if (rc)
			goto gpio6Fail;
static ssize_t vxr7200_enable_store(struct device *dev,
				 struct device_attribute *attr,
				const char *buf, size_t count)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct vxr7200 *pdata = i2c_get_clientdata(client);
	long val;
	int ret;

		rc = turnGpio(pdata, pdata->led_drive_en2,
					 "led_drive_en2", turnOn);
		if (rc)
			goto gpio7Fail;
	ret = kstrtol(buf, 0, &val);
	pr_debug("%s, count:%d  val:%lx, buf:%s\n",
				__func__, (int)count, val, buf);

	if (val == 0x1) {
		pr_debug("%s Turning on Display\n", __func__);
		pdata->enable = true;
		pdata->state = POWER_STATE_ENABLE;
		vxr7200_set_gpios(pdata, true);
	} else if (val == 0x0) {
		pr_debug("%s Turning off Display\n",
						 __func__);
		pdata->state = POWER_STATE_ENABLE;
		pdata->enable = false;
		vxr7200_set_gpios(pdata, false);
	} else
		pr_err("%s Invalid value. Valid vals(1-on,0-off)\n",
				__func__);

	return count;
}
	return;

gpio7Fail:
	gpio_free(pdata->led_drive_en2);
gpio6Fail:
	gpio_free(pdata->led_drive_en1);
gpio5Fail:
	gpio_free(pdata->led_5v_en);
gpio4Fail:
	gpio_free(pdata->mipi_switch_1v8_en);
gpio3Fail:
	gpio_free(pdata->display_1v8_en);
gpio2Fail:
	gpio_free(pdata->display_res1);
gpio1Fail:
	gpio_free(pdata->vxr_3v3_en);
static DEVICE_ATTR_RW(vxr7200_enable);

static struct attribute *vxr7200_fs_attrs[] = {
	&dev_attr_vxr7200_enable.attr,
	NULL
};

static struct attribute_group vxr7200_fs_attr_group = {
	.attrs = vxr7200_fs_attrs,
};

void vxr7200_usb_event(bool cable_plug)
{
	pr_debug("%s, cable_plug:%d\n", __func__, cable_plug);
	if (pdata) {
		pdata->state = POWER_STATE_POWERKEY;
		if (cable_plug) {
			pdata->usb_plugged = true;
			vxr7200_set_gpios(pdata, true);
		} else {
			pdata->usb_plugged = false;
			vxr7200_set_gpios(pdata, false);
		}
	}
}
EXPORT_SYMBOL(vxr7200_usb_event);

static int vxr7200_parse_dt(struct device *dev,
				struct vxr7200 *pdata)
@@ -185,57 +210,102 @@ static int vxr7200_parse_dt(struct device *dev,
	pdata->vxr_3v3_en =
		of_get_named_gpio(np, "qcom,vxr_3v3_en", 0);
	if (!gpio_is_valid(pdata->vxr_3v3_en)) {
		pr_err("vxr_3v3_en gpio not specified\n");
		pr_err("vxr7200_3v3_en gpio not specified\n");
		rc = -EINVAL;
	}
	if (gpio_request(pdata->vxr_3v3_en, "vxr_3v3_en")) {
		pr_err("vxr7200_3v3_en request gpio failed\n");
		rc = -EINVAL;
		goto gpio1Fail;
	}

	pdata->led_5v_en =
		of_get_named_gpio(np, "qcom,led-5v-en-gpio", 0);
	if (!gpio_is_valid(pdata->led_5v_en)) {
		pr_err("led_5v_en gpio not specified\n");
		pr_err("vxr7200_led_5v_en gpio not specified\n");
		rc = -EINVAL;
	}
	if (gpio_request(pdata->led_5v_en, "led_5v_en")) {
		pr_err("vxr7200_led_5v_en request gpio failed\n");
		rc = -EINVAL;
		goto gpio2Fail;
	}

	pdata->led_drive_en1 =
		of_get_named_gpio(np, "qcom,led-driver-en1-gpio", 0);
	if (!gpio_is_valid(pdata->led_drive_en1)) {
		pr_err("led_drive_en1 gpio not specified\n");
		pr_err("vxr7200_led_drive_en1 gpio not specified\n");
		rc = -EINVAL;
	}
	if (gpio_request(pdata->led_drive_en1, "led_drive_en1")) {
		pr_err("vxr7200_led_drive_en1 request gpio failed\n");
		rc = -EINVAL;
		goto gpio3Fail;
	}

	pdata->led_drive_en2 =
		of_get_named_gpio(np, "qcom,led-driver-en2-gpio", 0);
	if (!gpio_is_valid(pdata->led_drive_en2)) {
		pr_err("led_drive_en2 gpio not specified\n");
		pr_err("vxr7200_led_drive_en2 gpio not specified\n");
		rc = -EINVAL;
	}
	if (gpio_request(pdata->led_drive_en2, "led_drive_en2")) {
		pr_err("vxr7200_led_drive_en2 request gpio failed\n");
		rc = -EINVAL;
		goto gpio4Fail;
	}

	pdata->display_1v8_en =
		of_get_named_gpio(np, "qcom,1p8-en-gpio", 0);
	if (!gpio_is_valid(pdata->display_1v8_en)) {
		pr_err("display_1v8_en gpio not specified\n");
		pr_err("vxr7200_display_1v8_en gpio not specified\n");
		rc = -EINVAL;
	}
	if (gpio_request(pdata->display_1v8_en, "display_1v8_en")) {
		pr_err("vxr7200_display_1v8_en request gpio failed\n");
		rc = -EINVAL;
		goto gpio5Fail;
	}

	pdata->mipi_switch_1v8_en =
		of_get_named_gpio(np, "qcom,switch-power-gpio", 0);
	if (!gpio_is_valid(pdata->mipi_switch_1v8_en)) {
		pr_err("mipi_switch_1v8_en gpio not specified\n");
		pr_err("vxr7200_mipi_switch_1v8_en gpio not specified\n");
		rc = -EINVAL;
	}
	if (gpio_request(pdata->mipi_switch_1v8_en, "mipi_switch_1v8_en")) {
		pr_err("vxr7200_mipi_switch_1v8_en request gpio failed\n");
		rc = -EINVAL;
		goto gpio6Fail;
	}

	pdata->display_res1 =
		of_get_named_gpio(np, "qcom,platform-reset-gpio", 0);
	if (!gpio_is_valid(pdata->display_res1)) {
		pr_err("display_res1 gpio not specified\n");
		pr_err("vxr7200_display_res1 gpio not specified\n");
		rc = -EINVAL;
	}
	if (gpio_request(pdata->display_res1, "display_res1")) {
		pr_err("vxr7200_display_res1 request gpio failed\n");
		rc = -EINVAL;
		goto gpio7Fail;
	}
	return rc;

	if (!rc)
		vxr7200_set_gpios(pdata, true);

	if (!pdata->gpioInit)
		pdata->gpioInit = true;
gpio7Fail:
	gpio_free(pdata->display_res1);
gpio6Fail:
	gpio_free(pdata->mipi_switch_1v8_en);
gpio5Fail:
	gpio_free(pdata->display_1v8_en);
gpio4Fail:
	gpio_free(pdata->led_drive_en2);
gpio3Fail:
	gpio_free(pdata->led_drive_en1);
gpio2Fail:
	gpio_free(pdata->led_5v_en);
gpio1Fail:
	gpio_free(pdata->vxr_3v3_en);

	return rc;
}
@@ -319,7 +389,6 @@ static int vxr7200_probe(struct i2c_client *client,
	const struct i2c_device_id *id)
{
	int rc;
	struct vxr7200 *pdata;
	u8 reg[4] = {0x00, 0x20, 0x01, 0x60};
	u8 buf[4] = {0x00, 0x0, 0x0, 0x0};

@@ -341,7 +410,8 @@ static int vxr7200_probe(struct i2c_client *client,
	if (!pdata)
		return -ENOMEM;

	pdata->gpioInit = false;
	pdata->state = POWER_STATE_POWERKEY;
	pdata->enable = true;

	rc = vxr7200_parse_dt(&client->dev, pdata);
	if (rc) {
@@ -351,6 +421,14 @@ static int vxr7200_probe(struct i2c_client *client,
	pdata->dev = &client->dev;
	pdata->i2c_client = client;

	rc = sysfs_create_group(&pdata->dev->kobj, &vxr7200_fs_attr_group);
	if (rc) {
		pr_err("%s unable to register vxr7200 sysfs nodes\n",
					 __func__);
		goto err_dt_parse;
	}


	vxr7200_display_pwr_enable_vregs(pdata);

	i2c_set_clientdata(client, pdata);
@@ -359,6 +437,8 @@ static int vxr7200_probe(struct i2c_client *client,
	//vxr7200_write(pdata, 0x0A, 0x02);//Enable 4-lane DP
	vxr7200_read(pdata, reg, buf, 4);//Enable 4-lane DP

	return rc;

err_dt_parse:
	devm_kfree(&client->dev, pdata);

@@ -369,8 +449,10 @@ static int vxr7200_remove(struct i2c_client *client)
{
	struct vxr7200 *pdata = i2c_get_clientdata(client);

	if (pdata)
	if (pdata) {
		sysfs_remove_group(&pdata->dev->kobj, &vxr7200_fs_attr_group);
		devm_kfree(&client->dev, pdata);
	}
	return 0;
}

@@ -380,30 +462,13 @@ static void vxr7200_shutdown(struct i2c_client *client)
	dev_info(&(client->dev), "shutdown");
}

static int vxr7200_pm_freeze(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct vxr7200 *pdata = i2c_get_clientdata(client);

	dev_info(dev, "freeze");
	vxr7200_set_gpios(pdata, false);
	return 0;
}
static int vxr7200_pm_restore(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct vxr7200 *pdata = i2c_get_clientdata(client);

	dev_info(dev, "restore");
	vxr7200_set_gpios(pdata, true);
	return 0;
}
static int vxr7200_pm_suspend(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct vxr7200 *pdata = i2c_get_clientdata(client);

	dev_info(dev, "suspend");
	pdata->state = POWER_STATE_POWERKEY;
	vxr7200_set_gpios(pdata, false);
	return 0;
}
@@ -414,6 +479,7 @@ static int vxr7200_pm_resume(struct device *dev)
	struct vxr7200 *pdata = i2c_get_clientdata(client);

	dev_info(dev, "resume");
	pdata->state = POWER_STATE_POWERKEY;
	vxr7200_set_gpios(pdata, true);
	return 0;
}
@@ -421,9 +487,6 @@ static int vxr7200_pm_resume(struct device *dev)
static const struct dev_pm_ops vxr7200_dev_pm_ops = {
	.suspend	= vxr7200_pm_suspend,
	.resume	 = vxr7200_pm_resume,
	.freeze	 = vxr7200_pm_freeze,
	.restore	= vxr7200_pm_restore,
	.thaw	   = vxr7200_pm_restore,
	.poweroff	= vxr7200_pm_suspend,
};

drivers/misc/vxr7200.h

0 → 100644
+18 −0
Original line number Diff line number Diff line
/* Copyright (c) 2020 The Linux Foundation. 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 version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * 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.
 */

#ifndef __VXR7200_H_
#define __VXR7200_H_

void vxr7200_usb_event(bool usb_plug);

#endif /* __VXR7200_H_ */