46b578a620465ef821e33b0b89055ef557856c67
[cascardo/linux.git] / drivers / gpu / drm / bridge / anx7808.c
1 /*
2  * Copyright (C) 2013 Google, Inc.
3  *
4  * This software is licensed under the terms of the GNU General Public
5  * License version 2, as published by the Free Software Foundation, and
6  * may be copied, distributed, and modified under those terms.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * Based on code obtained from Analogix Inc with copyright:
14  * Copyright(c) 2012, Analogix Semiconductor. All rights reserved.
15  *
16  */
17
18 #include <linux/delay.h>
19 #include <linux/device.h>
20 #include <linux/i2c.h>
21 #include <linux/kernel.h>
22 #include <linux/module.h>
23 #include <linux/of_gpio.h>
24 #include <linux/regulator/consumer.h>
25 #include "drmP.h"
26
27 struct anx7808_data {
28         int pd_gpio;
29         int reset_gpio;
30         int intp_gpio;
31         int cable_det_gpio;
32         struct regulator *vdd_mydp;
33 };
34
35 static void anx7808_free_gpios(struct anx7808_data *anx7808)
36 {
37         gpio_free(anx7808->cable_det_gpio);
38         gpio_free(anx7808->intp_gpio);
39         gpio_free(anx7808->reset_gpio);
40         gpio_free(anx7808->pd_gpio);
41 }
42
43 static int anx7808_probe(struct i2c_client *client,
44                         const struct i2c_device_id *id)
45 {
46         int ret = 0;
47         struct device_node *node = client->dev.of_node;
48         struct anx7808_data *anx7808;
49
50         anx7808 = devm_kzalloc(&client->dev, sizeof(struct anx7808_data),
51                                GFP_KERNEL);
52         if (!anx7808) {
53                 DRM_ERROR("Failed to allocate platform_data.\n");
54                 return -ENOMEM;
55         }
56         i2c_set_clientdata(client, anx7808);
57
58         anx7808->vdd_mydp = regulator_get(&client->dev, "vdd_mydp");
59         if (IS_ERR(anx7808->vdd_mydp)) {
60                 DRM_ERROR("Failed to find regulator vdd_mydp.\n");
61                 return PTR_ERR(anx7808->vdd_mydp);
62         }
63
64         anx7808->pd_gpio = of_get_named_gpio(node, "pd-gpio", 0);
65         if (!gpio_is_valid(anx7808->pd_gpio)) {
66                 DRM_ERROR("Failed to locate pd-gpio.\n");
67                 ret = anx7808->pd_gpio;
68                 goto err_reg;
69         }
70
71         anx7808->reset_gpio = of_get_named_gpio(node, "reset-gpio", 0);
72         if (!gpio_is_valid(anx7808->reset_gpio)) {
73                 DRM_ERROR("Failed to locate reset-gpio.\n");
74                 ret = anx7808->reset_gpio;
75                 goto err_reg;
76         }
77
78         anx7808->intp_gpio = of_get_named_gpio(node, "intp-gpio", 0);
79         if (!gpio_is_valid(anx7808->intp_gpio)) {
80                 DRM_ERROR("Failed to locate intp-gpio.\n");
81                 ret = anx7808->intp_gpio;
82                 goto err_reg;
83         }
84
85         anx7808->cable_det_gpio = of_get_named_gpio(node, "cable-det-gpio", 0);
86         if (!gpio_is_valid(anx7808->cable_det_gpio)) {
87                 DRM_ERROR("Failed to locate cable-det-gpio.\n");
88                 ret = anx7808->cable_det_gpio;
89                 goto err_reg;
90         }
91
92         ret = gpio_request_one(anx7808->pd_gpio, GPIOF_OUT_INIT_HIGH,
93                                "anx7808_pd_gpio");
94         if (ret) {
95                 DRM_ERROR("Failed to request pd_gpio.\n");
96                 goto err_gpio;
97         }
98
99         ret = gpio_request_one(anx7808->reset_gpio, GPIOF_OUT_INIT_LOW,
100                                "anx7808_reset_gpio");
101         if (ret) {
102                 DRM_ERROR("Failed to request reset_gpio.\n");
103                 goto err_gpio;
104         }
105
106         ret = gpio_request_one(anx7808->intp_gpio, GPIOF_DIR_IN,
107                                "anx7808_intp_gpio");
108         if (ret) {
109                 DRM_ERROR("Failed to request intp_gpio.\n");
110                 goto err_gpio;
111         }
112
113         ret = gpio_request_one(anx7808->cable_det_gpio, GPIOF_DIR_IN,
114                                "anx7808_cable_det_gpio");
115         if (ret) {
116                 DRM_ERROR("Failed to request cable_det_gpio.\n");
117                 goto err_gpio;
118         }
119
120         DRM_INFO("ANX7808 initialization successful.\n");
121
122         return 0;
123 err_gpio:
124         anx7808_free_gpios(anx7808);
125 err_reg:
126         regulator_put(anx7808->vdd_mydp);
127         return ret;
128 }
129
130 static int anx7808_remove(struct i2c_client *client)
131 {
132         struct anx7808_data *anx7808 = i2c_get_clientdata(client);
133         anx7808_free_gpios(anx7808);
134         regulator_put(anx7808->vdd_mydp);
135         return 0;
136 }
137
138 static const struct i2c_device_id anx7808_id[] = {
139         { "anx7808", 0 },
140         { }
141 };
142
143 MODULE_DEVICE_TABLE(i2c, anx7808_id);
144
145 static struct i2c_driver anx7808_driver = {
146         .driver = {
147                 .name = "anx7808",
148                 .owner = THIS_MODULE,
149         },
150         .probe = anx7808_probe,
151         .remove = anx7808_remove,
152         .id_table = anx7808_id,
153 };
154
155 static int __init anx7808_init(void)
156 {
157         int ret = 0;
158
159         ret = i2c_add_driver(&anx7808_driver);
160         if (ret < 0)
161                 DRM_ERROR("Failed to register anx7808 i2c driver.\n");
162         return ret;
163 }
164
165 static void __exit anx7808_exit(void)
166 {
167         i2c_del_driver(&anx7808_driver);
168 }
169
170 module_init(anx7808_init);
171 module_exit(anx7808_exit);
172
173 MODULE_DESCRIPTION("ANX7808 driver");
174 MODULE_AUTHOR("Jeremy Thorpe <jeremyt@chromium.org>");
175 MODULE_LICENSE("GPL");