GPIO mux and configurations based on msm

1  files

board-8930-pmic.o board-8960-display.o board-8930-regulator-pm8038.o board-8960-gpiomux.o

board-8930-camera.o board-8930-regulator-pm8917.o board-8960.o
board-8930-display.o board-8930-storage.o board-8960-pmic.o
board-8930-gpiomux.o board-8960-regulator.o
board-8930-gpu.o               board-8960-storage.o
board-8930.o                   board-8960-camera.o

2  datasheet gpio registers explaination

The reset state for all GPIOs is as an input. Thedefault drive setting for all GPIOs is"000"(2mA).

To drive the output pad as a general purpose output, first configure the GPIO for alternate function 0. 


GPIO_CFGn, n = [0...151]

BITs[31:10] reserved

BITs[9]: GPIO_OE1 bit that controls the OE for GPIO[n] when in GPIO mode

BITs[8:6] DRV_STRENGTH000: 2mA, 001: 4mA, 010: 6mA, 011: 8mA, 100: 10mA, 101: 12mA, 110: 14mA, 111: 16mA

BITs[5:2] FUNC_SEL Many of the GPIO pads have one or more functional hardware interfaces behind them. This field controls how the pad is used

BITS[1:0] GPIO_PULL00: No pull; 01: pull down; 10: keeper; 11: pull up (internal weak pull up, down or keeper function)


unused:

/* Unused pins. Masked it here first before you use it */
static struct msm_gpiomux_config
		msm8930_unused_gpio_pins_config[] __initdata = {
	{.gpio = 1,    .settings[GPIOMUX_SUSPENDED] =  &unused_gpio_pins,},
};

static struct gpiomux_setting unused_gpio_pins = {
	.func = GPIOMUX_FUNC_GPIO,
	.drv = GPIOMUX_DRV_2MA,
	.pull = GPIOMUX_PULL_DOWN,
};

used(sdcard detect):

static struct gpiomux_setting sd_det_line = {
	.func = GPIOMUX_FUNC_GPIO,
	.drv = GPIOMUX_DRV_2MA,
	.pull = GPIOMUX_PULL_UP,
};

static struct msm_gpiomux_config msm8960_sd_det_config[] __initdata = {
	{
		.gpio = 94,		/* SD Card Detect Line */
		.settings = {
			[GPIOMUX_SUSPENDED] = &sd_det_line,
			[GPIOMUX_ACTIVE] = &sd_det_line,
		},
	},
};
used(I2C):

static struct msm_gpiomux_config msm8960_gsbi3_configs[] __initdata = {
	{
		.gpio      = 16,	/* GSBI3 I2C QUP SDA */
		.settings = {           /* touchscreen i2c bus */
			[GPIOMUX_SUSPENDED] = &gsbi3_suspended_cfg,
			[GPIOMUX_ACTIVE] = &gsbi3_active_cfg,
		},
	},
	{
		.gpio      = 17,	/* GSBI3 I2C QUP SCL */
		.settings = {
			[GPIOMUX_SUSPENDED] = &gsbi3_suspended_cfg,
			[GPIOMUX_ACTIVE] = &gsbi3_active_cfg,
		},
	},
};
static struct gpiomux_setting gsbi3_suspended_cfg = {
	.func = GPIOMUX_FUNC_1,
	.drv = GPIOMUX_DRV_2MA,
	.pull = GPIOMUX_PULL_KEEPER,
};

static struct gpiomux_setting gsbi3_active_cfg = {
	.func = GPIOMUX_FUNC_1,
	.drv = GPIOMUX_DRV_8MA,
	.pull = GPIOMUX_PULL_NONE,
};

install:

int __init msm8930_init_gpiomux(void)
	int rc = msm_gpiomux_init(NR_GPIO_IRQS);

	msm_gpiomux_install(msm8960_sd_det_config,
			ARRAY_SIZE(msm8960_sd_det_config));

3  code related to lcd

LCD reset pin:

static struct msm_gpiomux_config msm8960_lcd_config[] __initdata = {
	{
		.gpio	= 58,		/* lcd reset pin */
		.settings = {
			[GPIOMUX_SUSPENDED] = &lcd_rst_n_suspend,
			[GPIOMUX_ACTIVE] = &lcd_rst_n_active,
		},
	},
};


LCD reset function:

#define DISP_RST_GPIO 58
static int mipi_dsi_cdp_panel_power(int on)
{
	/* keep the power supply of L9 and LVS2 except L2. */
	static struct regulator *lcd_ic_vdd, *lcd_ic_vio, *host_mipi_vioa;

	/* Control backlight GPIO (24) directly when using PM8917 */
	int gpio24 = PM8917_GPIO_PM_TO_SYS(24);
	int rc;

	pr_debug("%s: state : %d\n", __func__, on);

	if (!dsi_power_on) {

		lcd_ic_vdd = regulator_get(&msm_mipi_dsi1_device.dev,
				"dsi_vdc");
		if (IS_ERR(lcd_ic_vdd)) {
			pr_err("could not get lcd_ic_vdd, rc = %ld\n",
				PTR_ERR(lcd_ic_vdd));
			return -ENODEV;
		}
		lcd_ic_vio = regulator_get(&msm_mipi_dsi1_device.dev,
				"dsi_vddio");
		if (IS_ERR(lcd_ic_vio)) {
			pr_err("could not get lcd_ic_vio, rc = %ld\n",
				PTR_ERR(lcd_ic_vio));
			return -ENODEV;
		}
		host_mipi_vioa = regulator_get(&msm_mipi_dsi1_device.dev,
				"dsi_vdda");
		if (IS_ERR(host_mipi_vioa)) {
			pr_err("could not get host_mipi_vioa, rc = %ld\n",
				PTR_ERR(host_mipi_vioa));
			return -ENODEV;
		}
		rc = regulator_set_voltage(lcd_ic_vdd, 2800000, 3000000);
		if (rc) {
			pr_err("set_voltage lcd_ic_vdd failed, rc=%d\n", rc);
			return -EINVAL;
		}
		if (regulator_count_voltages(lcd_ic_vio) > 0) {
			rc = regulator_set_voltage(lcd_ic_vio, 1800000, 1800000);
			if (rc) {
				pr_err("set_voltage lcd_ic_vio failed, rc=%d\n", rc);
				return -EINVAL;
			}
		}
		rc = regulator_set_voltage(host_mipi_vioa, 1200000, 1200000);
		if (rc) {
			pr_err("set_voltage host_mipi_vioa failed, rc=%d\n", rc);
			return -EINVAL;
		}
		rc = regulator_set_optimum_mode(lcd_ic_vdd, 100000);
		if (rc < 0) {
			pr_err("set_optimum_mode lcd_ic_vdd failed, rc=%d\n", rc);
			return -EINVAL;
		}
		rc = regulator_set_optimum_mode(lcd_ic_vio, 100000);
		if (rc < 0) {
			pr_err("set_optimum_mode lcd_ic_vio failed, rc=%d\n", rc);
			return -EINVAL;
		}
		rc = regulator_enable(lcd_ic_vdd);
		if (rc) {
			pr_err("enable lcd_ic_vdd failed, rc=%d\n", rc);
			return -ENODEV;
		}
		rc = regulator_enable(lcd_ic_vio);
		if (rc) {
			pr_err("enable lcd_ic_vio failed, rc=%d\n", rc);
			return -ENODEV;
		}
		rc = gpio_request(DISP_RST_GPIO, "disp_rst_n");
		if (rc) {
			pr_err("request gpio DISP_RST_GPIO failed, rc=%d\n",
				rc);
			gpio_free(DISP_RST_GPIO);
			return -ENODEV;
		}
		if (machine_is_msm8930_evt()) {
			rc = gpio_direction_output(DISP_RST_GPIO, 1);
			if (rc) {
				pr_err("gpio_direction_output failed for %d gpio rc=%d\n",
						DISP_RST_GPIO, rc);
				return -ENODEV;
			}
		}

		if (socinfo_get_pmic_model() == PMIC_MODEL_PM8917) {
			rc = gpio_request(gpio24, "disp_bl");
			if (rc) {
				pr_err("request for gpio 24 failed, rc=%d\n",
					rc);
				return -ENODEV;
			}
			gpio_set_value_cansleep(gpio24, 0);
			novatek_pdata.gpio_set_backlight =
				pm8917_gpio_set_backlight;
		}
		dsi_power_on = true;
	}

	if (on) {
		rc = regulator_set_optimum_mode(host_mipi_vioa, 100000);
		if (rc < 0) {
			pr_err("set_optimum_mode host_mipi_vioa failed, rc=%d\n", rc);
			return -EINVAL;
		}
		rc = regulator_enable(host_mipi_vioa);
		if (rc) {
			pr_err("enable host_mipi_vioa failed, rc=%d\n", rc);
			return -ENODEV;
		}

		/* Reset lcd driver ic */
		gpio_set_value(DISP_RST_GPIO, 1);
		msleep(1);
		gpio_set_value(DISP_RST_GPIO, 0);
		msleep(2);
		gpio_set_value(DISP_RST_GPIO, 1);
		msleep(20);
	} else {

		rc = regulator_disable(host_mipi_vioa);
		if (rc) {
			pr_err("disable host_mipi_vioa failed, rc=%d\n", rc);
			return -ENODEV;
		}
		rc = regulator_set_optimum_mode(host_mipi_vioa, 100);
		if (rc < 0) {
			pr_err("set_optimum_mode host_mipi_vioa failed, rc=%d\n", rc);
			return -EINVAL;
		}
	}
	return 0;
}

static int mipi_dsi_panel_power(int on)
{
	pr_debug("%s: on=%d\n", __func__, on);

	return mipi_dsi_cdp_panel_power(on);
}

static struct mipi_dsi_platform_data mipi_dsi_pdata = {
	.vsync_gpio = MDP_VSYNC_GPIO,
	.dsi_power_save = mipi_dsi_panel_power,
	.splash_is_enabled = mipi_dsi_splash_is_enabled,
};

void __init msm8930_init_fb(void)
{
	platform_device_register(&msm_fb_device);

	platform_device_register(&mipi_dsi_NT35590_panel_device);
#ifdef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
	platform_device_register(&wfd_panel_device);
	platform_device_register(&wfd_device);
#endif

	platform_device_register(&mipi_dsi_novatek_panel_device);

#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
	platform_device_register(&hdmi_msm_device);
#endif

	platform_device_register(&mipi_dsi_toshiba_panel_device);

#ifdef CONFIG_FB_MSM_MIPI_GLOBAL_VIDEO_QHD_PT_PANEL
	platform_device_register(&mipi_dsi_global_panel_device);
#endif
	msm_fb_register_device("mdp", &mdp_pdata);
	msm_fb_register_device("mipi_dsi", &mipi_dsi_pdata);
#ifdef CONFIG_MSM_BUS_SCALING
	msm_fb_register_device("dtv", &dtv_pdata);
#endif
}

void __init msm8930_allocate_fb_region(void)
{
	void *addr;
	unsigned long size;

	size = MSM_FB_SIZE;
	addr = alloc_bootmem_align(size, 0x1000);
	msm_fb_resources[0].start = __pa(addr);
	msm_fb_resources[0].end = msm_fb_resources[0].start + size - 1;
	pr_info("allocating %lu bytes at %p (%lx physical) for fb\n",
			size, addr, __pa(addr));
}

mipi_dsi_off ->
mipi_dsi_pdata->dsi_power_save(0);

mipi_dsi_on ->
mipi_dsi_pdata->dsi_power_save(1);

4  code related to synaptics ic

4.1 gpio definition ( board-8930-gpiomux.c)
static struct msm_gpiomux_config msm8960_touch_gpio_configs[] __initdata = {
	{	/* touch ic interrupt pin */
		.gpio = 11,
		.settings = {
			[GPIOMUX_ACTIVE]    = &xxx, // 8mA, pull up
			[GPIOMUX_SUSPENDED] = &xxx, // 2mA, pull up
		},
	},
	{	/* touch ic RESET pin */
		.gpio = 52,
		.settings = {
			[GPIOMUX_ACTIVE]    = &xxx, // 6mA, pull up
			[GPIOMUX_SUSPENDED] = &xxx, // 6mA, pull up
		},
	},
};

static struct msm_gpiomux_config msm8960_gsbi3_configs[] __initdata = {
	{
		.gpio      = 16,	/* GSBI3 I2C QUP SDA */
		.settings = {           /* touchscreen i2c bus */
			[GPIOMUX_SUSPENDED] = &gsbi3_suspended_cfg,
			[GPIOMUX_ACTIVE] = &gsbi3_active_cfg,
		},
	},
	{
		.gpio      = 17,	/* GSBI3 I2C QUP SCL */
		.settings = {
			[GPIOMUX_SUSPENDED] = &gsbi3_suspended_cfg,
			[GPIOMUX_ACTIVE] = &gsbi3_active_cfg,
		},
	},
};

static struct gpiomux_setting gsbi3_suspended_cfg = {
	.func = GPIOMUX_FUNC_1,
	.drv = GPIOMUX_DRV_2MA,
	.pull = GPIOMUX_PULL_KEEPER,
};

static struct gpiomux_setting gsbi3_active_cfg = {
	.func = GPIOMUX_FUNC_1,
	.drv = GPIOMUX_DRV_8MA,
	.pull = GPIOMUX_PULL_NONE,
};

msm_gpiomux_install(msm8960_gsbi3_configs, ARRAY_SIZE(msm8960_gsbi3_configs));

4.2 board information

#ifdef CONFIG_RMI4_I2C

#define SYNAPTIC_ADDR 0x20
#define SYNAPTIC_ATTEN_GPIO (11)
#define SYNAPTIC_RESET_GPIO (52)

static unsigned char synaptic_rmi4_button_codes[] = {KEY_BACK, KEY_HOME, KEY_MENU};

static struct rmi_f1a_button_map synaptic_rmi4_button_map = {
	.nbuttons = ARRAY_SIZE(synaptic_rmi4_button_codes),
	.map = synaptic_rmi4_button_codes,
};

static int synaptic_ic_gpio_init(void *gpio_data, bool configure)
{
	int rc = 0 ;

	pr_debug("%s: synaptics s2202/3202 gpio init start.\n", __func__);
	if (!configure) {
		pr_err("%s: Can't config gpio.\n", __func__);
		return -1;
	}

	rc = gpio_request(SYNAPTIC_ATTEN_GPIO, "S2202_irq_gpio");
	if (rc) {
		pr_err("%s: irq gpio request failed (rc = %d)!\n",
			__func__, rc);
		return -1;
	}

	rc = gpio_request(SYNAPTIC_RESET_GPIO, "S2202_reset_gpio");
	if (rc) {
		pr_err("%s: reset gpio request failed (rc = %d)!\n",
			__func__, rc);
		gpio_free(SYNAPTIC_ATTEN_GPIO);
		return -1;
	}

	gpio_direction_output(SYNAPTIC_RESET_GPIO, 1);
	msleep(10);
	gpio_direction_output(SYNAPTIC_RESET_GPIO, 0);
	msleep(10);
	gpio_direction_output(SYNAPTIC_RESET_GPIO, 1);
	msleep(100);

	msleep(100);
	gpio_direction_input(SYNAPTIC_ATTEN_GPIO);
	pr_debug("%s: Synaptics s2202/s3202 gpio set successfully.\n", __func__);

	return 0;
}

static struct rmi_device_platform_data rmi4_platformdata = {
	.driver_name = "rmi_controller",
	.level_triggered = 1,
	.attn_gpio = SYNAPTIC_ATTEN_GPIO,
	.attn_polarity = RMI_ATTN_ACTIVE_LOW,
	.gpio_config = synaptic_ic_gpio_init,
	.f1a_button_map = &synaptic_rmi4_button_map,
};

static struct i2c_board_info rmi4_i2c_devices[] = {
	{
		I2C_BOARD_INFO("rmi_i2c", SYNAPTIC_ADDR),
		.platform_data =  &rmi4_platformdata,
		.irq = MSM_GPIO_TO_INT(TOUCH_INT_GPIO),
	},
};
#endif


static struct i2c_registry msm8960_i2c_devices[] __initdata = {
#ifdef CONFIG_RMI4_I2C
	{
		I2C_SURF | I2C_FFA | I2C_FLUID,
		MSM_8930_GSBI3_QUP_I2C_BUS_ID,
		rmi4_i2c_devices,
		ARRAY_SIZE(rmi4_i2c_devices),
	},
#endif
}

 
	/* Run the array and install devices as appropriate */
	for (i = 0; i < ARRAY_SIZE(msm8960_i2c_devices); ++i) {
		if (msm8960_i2c_devices[i].machs & mach_mask)
			i2c_register_board_info(msm8960_i2c_devices[i].bus,
						msm8960_i2c_devices[i].info,
						msm8960_i2c_devices[i].len);
	}

->  register_i2c_devices  ->  msm8930_cdp_init  ->  

MACHINE_START(MSM8930_CDP, "QCT MSM8930 CDP")
	.map_io = msm8930_map_io,
	.reserve = msm8930_reserve,
	.init_irq = msm8930_init_irq,
	.handle_irq = gic_handle_irq,
	.timer = &msm_timer,
	.init_machine = msm8930_cdp_init,
	.init_early = msm8930_allocate_memory_regions,
	.init_very_early = msm8930_early_memory,
	.restart = msm_restart,
MACHINE_END





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值