--- /dev/null
+/*
+ * Copyright (C) 2013 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Based on code obtained from Analogix Inc with copyright:
+ * Copyright(c) 2012, Analogix Semiconductor. All rights reserved.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_gpio.h>
+#include <linux/regulator/consumer.h>
+#include "drmP.h"
+
+struct anx7808_data {
+ int pd_gpio;
+ int reset_gpio;
+ int intp_gpio;
+ int cable_det_gpio;
+ struct regulator *vdd_mydp;
+};
+
+static void anx7808_free_gpios(struct anx7808_data *anx7808)
+{
+ gpio_free(anx7808->cable_det_gpio);
+ gpio_free(anx7808->intp_gpio);
+ gpio_free(anx7808->reset_gpio);
+ gpio_free(anx7808->pd_gpio);
+}
+
+static int anx7808_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int ret = 0;
+ struct device_node *node = client->dev.of_node;
+ struct anx7808_data *anx7808;
+
+ anx7808 = devm_kzalloc(&client->dev, sizeof(struct anx7808_data),
+ GFP_KERNEL);
+ if (!anx7808) {
+ DRM_ERROR("Failed to allocate platform_data.\n");
+ return -ENOMEM;
+ }
+ i2c_set_clientdata(client, anx7808);
+
+ anx7808->vdd_mydp = regulator_get(&client->dev, "vdd_mydp");
+ if (IS_ERR(anx7808->vdd_mydp)) {
+ DRM_ERROR("Failed to find regulator vdd_mydp.\n");
+ return PTR_ERR(anx7808->vdd_mydp);
+ }
+
+ anx7808->pd_gpio = of_get_named_gpio(node, "pd-gpio", 0);
+ if (!gpio_is_valid(anx7808->pd_gpio)) {
+ DRM_ERROR("Failed to locate pd-gpio.\n");
+ ret = anx7808->pd_gpio;
+ goto err_reg;
+ }
+
+ anx7808->reset_gpio = of_get_named_gpio(node, "reset-gpio", 0);
+ if (!gpio_is_valid(anx7808->reset_gpio)) {
+ DRM_ERROR("Failed to locate reset-gpio.\n");
+ ret = anx7808->reset_gpio;
+ goto err_reg;
+ }
+
+ anx7808->intp_gpio = of_get_named_gpio(node, "intp-gpio", 0);
+ if (!gpio_is_valid(anx7808->intp_gpio)) {
+ DRM_ERROR("Failed to locate intp-gpio.\n");
+ ret = anx7808->intp_gpio;
+ goto err_reg;
+ }
+
+ anx7808->cable_det_gpio = of_get_named_gpio(node, "cable-det-gpio", 0);
+ if (!gpio_is_valid(anx7808->cable_det_gpio)) {
+ DRM_ERROR("Failed to locate cable-det-gpio.\n");
+ ret = anx7808->cable_det_gpio;
+ goto err_reg;
+ }
+
+ ret = gpio_request_one(anx7808->pd_gpio, GPIOF_OUT_INIT_HIGH,
+ "anx7808_pd_gpio");
+ if (ret) {
+ DRM_ERROR("Failed to request pd_gpio.\n");
+ goto err_gpio;
+ }
+
+ ret = gpio_request_one(anx7808->reset_gpio, GPIOF_OUT_INIT_LOW,
+ "anx7808_reset_gpio");
+ if (ret) {
+ DRM_ERROR("Failed to request reset_gpio.\n");
+ goto err_gpio;
+ }
+
+ ret = gpio_request_one(anx7808->intp_gpio, GPIOF_DIR_IN,
+ "anx7808_intp_gpio");
+ if (ret) {
+ DRM_ERROR("Failed to request intp_gpio.\n");
+ goto err_gpio;
+ }
+
+ ret = gpio_request_one(anx7808->cable_det_gpio, GPIOF_DIR_IN,
+ "anx7808_cable_det_gpio");
+ if (ret) {
+ DRM_ERROR("Failed to request cable_det_gpio.\n");
+ goto err_gpio;
+ }
+
+ DRM_INFO("ANX7808 initialization successful.\n");
+
+ return 0;
+err_gpio:
+ anx7808_free_gpios(anx7808);
+err_reg:
+ regulator_put(anx7808->vdd_mydp);
+ return ret;
+}
+
+static int anx7808_remove(struct i2c_client *client)
+{
+ struct anx7808_data *anx7808 = i2c_get_clientdata(client);
+ anx7808_free_gpios(anx7808);
+ regulator_put(anx7808->vdd_mydp);
+ return 0;
+}
+
+static const struct i2c_device_id anx7808_id[] = {
+ { "anx7808", 0 },
+ { }
+};
+
+MODULE_DEVICE_TABLE(i2c, anx7808_id);
+
+static struct i2c_driver anx7808_driver = {
+ .driver = {
+ .name = "anx7808",
+ .owner = THIS_MODULE,
+ },
+ .probe = anx7808_probe,
+ .remove = anx7808_remove,
+ .id_table = anx7808_id,
+};
+
+static int __init anx7808_init(void)
+{
+ int ret = 0;
+
+ ret = i2c_add_driver(&anx7808_driver);
+ if (ret < 0)
+ DRM_ERROR("Failed to register anx7808 i2c driver.\n");
+ return ret;
+}
+
+static void __exit anx7808_exit(void)
+{
+ i2c_del_driver(&anx7808_driver);
+}
+
+module_init(anx7808_init);
+module_exit(anx7808_exit);
+
+MODULE_DESCRIPTION("ANX7808 driver");
+MODULE_AUTHOR("Jeremy Thorpe <jeremyt@chromium.org>");
+MODULE_LICENSE("GPL");