History

drm/gma500: Pass GPIO for Intel MID using descriptors

The GMA500 driver is using the legacy GPIO API to fetch three optional display control GPIO lines from the SFI description used by the Medfield platform. Switch this over to use GPIO descriptors and delete the custom platform data. We create three new static locals in the tc35876x bridge code but it is hardly any worse than the I2C client static local already there: I tried first to move it to the DRM driver state container but there are workarounds for probe order in the code so I just stayed off it, as the result is unpredictable. People wanting to do a more throrugh and proper cleanup of the GMA500 driver can work on top of this, I can't solve much more since I don't have access to the hardware, I can only attempt to tidy up my GPIO corner.

Linus Walleij committed 6 years ago

Commit cd6a1ca1 parent 2840f1f3 files · +51 −74Browse files

Unified · Split

3 files
  1. arch/x86/platform/intel-mid/device_libs/platform_tc35876x.c +18 −8
  2. drivers/gpu/drm/gma500/tc35876x-dsi-lvds.c +33 −55
  3. include/linux/platform_data/tc35876x.h +0 −11
arch/x86/platform/intel-mid/device_libs/platform_tc35876x.c+18−8
@@ -6,21 +6,31 @@ · 5 unmodified lines
6 * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>6 * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
7 */7 */
8 8
9#include <linux/gpio.h>9#include <linux/gpio/machine.h>
10#include <linux/platform_data/tc35876x.h>
11#include <asm/intel-mid.h>10#include <asm/intel-mid.h>
12 11
12static struct gpiod_lookup_table tc35876x_gpio_table = {
13 .dev_id = "i2c_disp_brig",
14 .table = {
15 GPIO_LOOKUP("0000:00:0c.0", -1, "bridge-reset", GPIO_ACTIVE_HIGH),
16 GPIO_LOOKUP("0000:00:0c.0", -1, "bl-en", GPIO_ACTIVE_HIGH),
17 GPIO_LOOKUP("0000:00:0c.0", -1, "vadd", GPIO_ACTIVE_HIGH),
18 { },
19 },
20};
21
13/*tc35876x DSI_LVDS bridge chip and panel platform data*/22/*tc35876x DSI_LVDS bridge chip and panel platform data*/
14static void *tc35876x_platform_data(void *data)23static void *tc35876x_platform_data(void *data)
15{24{
16 static struct tc35876x_platform_data pdata;25 struct gpiod_lookup_table *table = &tc35876x_gpio_table;
26 struct gpiod_lookup *lookup = table->table;
17 27
18 /* gpio pins set to -1 will not be used by the driver */28 lookup[0].chip_hwnum = get_gpio_by_name("LCMB_RXEN");
19 pdata.gpio_bridge_reset = get_gpio_by_name("LCMB_RXEN");29 lookup[1].chip_hwnum = get_gpio_by_name("6S6P_BL_EN");
20 pdata.gpio_panel_bl_en = get_gpio_by_name("6S6P_BL_EN");30 lookup[2].chip_hwnum = get_gpio_by_name("EN_VREG_LCD_V3P3");
21 pdata.gpio_panel_vadd = get_gpio_by_name("EN_VREG_LCD_V3P3");31 gpiod_add_lookup_table(table);
22 32
23 return &pdata;33 return NULL;
24}34}
25 35
26static const struct devs_id tc35876x_dev_id __initconst = {36static const struct devs_id tc35876x_dev_id __initconst = {
drivers/gpu/drm/gma500/tc35876x-dsi-lvds.c+33−55
@@ -25,7 +25,7 @@ · 24 unmodified lines
25#include <linux/delay.h>25#include <linux/delay.h>
26#include <linux/kernel.h>26#include <linux/kernel.h>
27#include <linux/module.h>27#include <linux/module.h>
28#include <linux/platform_data/tc35876x.h>28#include <linux/gpio/consumer.h>
29 29
30#include <asm/intel_scu_ipc.h>30#include <asm/intel_scu_ipc.h>
31 31
@@ -36,6 +36,11 @@ · 4 unmodified lines
36 36
37static struct i2c_client *tc35876x_client;37static struct i2c_client *tc35876x_client;
38static struct i2c_client *cmi_lcd_i2c_client;38static struct i2c_client *cmi_lcd_i2c_client;
39/* Panel GPIOs */
40static struct gpio_desc *bridge_reset;
41static struct gpio_desc *bridge_bl_enable;
42static struct gpio_desc *backlight_voltage;
43
39 44
40#define FLD_MASK(start, end) (((1 << ((start) - (end) + 1)) - 1) << (end))45#define FLD_MASK(start, end) (((1 << ((start) - (end) + 1)) - 1) << (end))
41#define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end))46#define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end))
@@ -316,27 +321,23 @@ static int tc35876x_regr(struct i2c_client *client, u16 reg, u32 *value) · 274 unmodified lines
316 321
317void tc35876x_set_bridge_reset_state(struct drm_device *dev, int state)322void tc35876x_set_bridge_reset_state(struct drm_device *dev, int state)
318{323{
319 struct tc35876x_platform_data *pdata;
320
321 if (WARN(!tc35876x_client, "%s called before probe", __func__))324 if (WARN(!tc35876x_client, "%s called before probe", __func__))
322 return;325 return;
323 326
324 dev_dbg(&tc35876x_client->dev, "%s: state %d\n", __func__, state);327 dev_dbg(&tc35876x_client->dev, "%s: state %d\n", __func__, state);
325 328
326 pdata = dev_get_platdata(&tc35876x_client->dev);329 if (!bridge_reset)
327
328 if (pdata->gpio_bridge_reset == -1)
329 return;330 return;
330 331
331 if (state) {332 if (state) {
332 gpio_set_value_cansleep(pdata->gpio_bridge_reset, 0);333 gpiod_set_value_cansleep(bridge_reset, 0);
333 mdelay(10);334 mdelay(10);
334 } else {335 } else {
335 /* Pull MIPI Bridge reset pin to Low */336 /* Pull MIPI Bridge reset pin to Low */
336 gpio_set_value_cansleep(pdata->gpio_bridge_reset, 0);337 gpiod_set_value_cansleep(bridge_reset, 0);
337 mdelay(20);338 mdelay(20);
338 /* Pull MIPI Bridge reset pin to High */339 /* Pull MIPI Bridge reset pin to High */
339 gpio_set_value_cansleep(pdata->gpio_bridge_reset, 1);340 gpiod_set_value_cansleep(bridge_reset, 1);
340 mdelay(40);341 mdelay(40);
341 }342 }
342}343}
@@ -510,25 +511,20 @@ void tc35876x_brightness_control(struct drm_device *dev, int level) · 167 unmodified lines
510 511
511void tc35876x_toshiba_bridge_panel_off(struct drm_device *dev)512void tc35876x_toshiba_bridge_panel_off(struct drm_device *dev)
512{513{
513 struct tc35876x_platform_data *pdata;
514
515 if (WARN(!tc35876x_client, "%s called before probe", __func__))514 if (WARN(!tc35876x_client, "%s called before probe", __func__))
516 return;515 return;
517 516
518 dev_dbg(&tc35876x_client->dev, "%s\n", __func__);517 dev_dbg(&tc35876x_client->dev, "%s\n", __func__);
519 518
520 pdata = dev_get_platdata(&tc35876x_client->dev);519 if (bridge_bl_enable)
521 520 gpiod_set_value_cansleep(bridge_bl_enable, 0);
522 if (pdata->gpio_panel_bl_en != -1)
523 gpio_set_value_cansleep(pdata->gpio_panel_bl_en, 0);
524 521
525 if (pdata->gpio_panel_vadd != -1)522 if (backlight_voltage)
526 gpio_set_value_cansleep(pdata->gpio_panel_vadd, 0);523 gpiod_set_value_cansleep(backlight_voltage, 0);
527}524}
528 525
529void tc35876x_toshiba_bridge_panel_on(struct drm_device *dev)526void tc35876x_toshiba_bridge_panel_on(struct drm_device *dev)
530{527{
531 struct tc35876x_platform_data *pdata;
532 struct drm_psb_private *dev_priv = dev->dev_private;528 struct drm_psb_private *dev_priv = dev->dev_private;
533 529
534 if (WARN(!tc35876x_client, "%s called before probe", __func__))530 if (WARN(!tc35876x_client, "%s called before probe", __func__))
@@ -536,10 +532,8 @@ void tc35876x_toshiba_bridge_panel_on(struct drm_device *dev) · 1 unmodified line
536 532
537 dev_dbg(&tc35876x_client->dev, "%s\n", __func__);533 dev_dbg(&tc35876x_client->dev, "%s\n", __func__);
538 534
539 pdata = dev_get_platdata(&tc35876x_client->dev);535 if (backlight_voltage) {
540 536 gpiod_set_value_cansleep(backlight_voltage, 1);
541 if (pdata->gpio_panel_vadd != -1) {
542 gpio_set_value_cansleep(pdata->gpio_panel_vadd, 1);
543 msleep(260);537 msleep(260);
544 }538 }
545 539
@@ -571,8 +565,8 @@ void tc35876x_toshiba_bridge_panel_on(struct drm_device *dev) · 25 unmodified lines
571 "i2c write failed (%d)\n", ret);565 "i2c write failed (%d)\n", ret);
572 }566 }
573 567
574 if (pdata->gpio_panel_bl_en != -1)568 if (bridge_bl_enable)
575 gpio_set_value_cansleep(pdata->gpio_panel_bl_en, 1);569 gpiod_set_value_cansleep(bridge_bl_enable, 1);
576 570
577 tc35876x_brightness_control(dev, dev_priv->brightness_adjusted);571 tc35876x_brightness_control(dev, dev_priv->brightness_adjusted);
578}572}
@@ -635,8 +629,6 @@ static int tc35876x_get_panel_info(struct drm_device *dev, int pipe, · 56 unmodified lines
635static int tc35876x_bridge_probe(struct i2c_client *client,629static int tc35876x_bridge_probe(struct i2c_client *client,
636 const struct i2c_device_id *id)630 const struct i2c_device_id *id)
637{631{
638 struct tc35876x_platform_data *pdata;
639
640 dev_info(&client->dev, "%s\n", __func__);632 dev_info(&client->dev, "%s\n", __func__);
641 633
642 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {634 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
@@ -645,26 +637,23 @@ static int tc35876x_bridge_probe(struct i2c_client *client, · 2 unmodified lines
645 return -ENODEV;637 return -ENODEV;
646 }638 }
647 639
648 pdata = dev_get_platdata(&client->dev);640 bridge_reset = devm_gpiod_get_optional(&client->dev, "bridge-reset", GPIOD_OUT_LOW);
649 if (!pdata) {641 if (IS_ERR(bridge_reset))
650 dev_err(&client->dev, "%s: no platform data\n", __func__);642 return PTR_ERR(bridge_reset);
651 return -ENODEV;643 if (bridge_reset)
652 }644 gpiod_set_consumer_name(bridge_reset, "tc35876x bridge reset");
653 645
654 if (pdata->gpio_bridge_reset != -1) {646 bridge_bl_enable = devm_gpiod_get_optional(&client->dev, "bl-en", GPIOD_OUT_LOW);
655 gpio_request(pdata->gpio_bridge_reset, "tc35876x bridge reset");647 if (IS_ERR(bridge_bl_enable))
656 gpio_direction_output(pdata->gpio_bridge_reset, 0);648 return PTR_ERR(bridge_bl_enable);
657 }649 if (bridge_bl_enable)
658 650 gpiod_set_consumer_name(bridge_bl_enable, "tc35876x panel bl en");
659 if (pdata->gpio_panel_bl_en != -1) {
660 gpio_request(pdata->gpio_panel_bl_en, "tc35876x panel bl en");
661 gpio_direction_output(pdata->gpio_panel_bl_en, 0);
662 }
663 651
664 if (pdata->gpio_panel_vadd != -1) {652 backlight_voltage = devm_gpiod_get_optional(&client->dev, "vadd", GPIOD_OUT_LOW);
665 gpio_request(pdata->gpio_panel_vadd, "tc35876x panel vadd");653 if (IS_ERR(backlight_voltage))
666 gpio_direction_output(pdata->gpio_panel_vadd, 0);654 return PTR_ERR(backlight_voltage);
667 }655 if (backlight_voltage)
656 gpiod_set_consumer_name(backlight_voltage, "tc35876x panel vadd");
668 657
669 tc35876x_client = client;658 tc35876x_client = client;
670 659
@@ -673,19 +662,8 @@ static int tc35876x_bridge_probe(struct i2c_client *client, · 2 unmodified lines
673 662
674static int tc35876x_bridge_remove(struct i2c_client *client)663static int tc35876x_bridge_remove(struct i2c_client *client)
675{664{
676 struct tc35876x_platform_data *pdata = dev_get_platdata(&client->dev);
677
678 dev_dbg(&client->dev, "%s\n", __func__);665 dev_dbg(&client->dev, "%s\n", __func__);
679 666
680 if (pdata->gpio_bridge_reset != -1)
681 gpio_free(pdata->gpio_bridge_reset);
682
683 if (pdata->gpio_panel_bl_en != -1)
684 gpio_free(pdata->gpio_panel_bl_en);
685
686 if (pdata->gpio_panel_vadd != -1)
687 gpio_free(pdata->gpio_panel_vadd);
688
689 tc35876x_client = NULL;667 tc35876x_client = NULL;
690 668
691 return 0;669 return 0;
include/linux/platform_data/tc35876x.h+0−11
@@ -1,11 +0,0 @@
1
2#ifndef _TC35876X_H
3#define _TC35876X_H
4
5struct tc35876x_platform_data {
6 int gpio_bridge_reset;
7 int gpio_panel_bl_en;
8 int gpio_panel_vadd;
9};
10
11#endif /* _TC35876X_H */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t