Skip to content

Commit

Permalink
Gonzo sysfs driver for controlling LEDs.
Browse files Browse the repository at this point in the history
  • Loading branch information
tlan committed Jan 29, 2015
1 parent 2ca8e9d commit 6c07642
Show file tree
Hide file tree
Showing 3 changed files with 165 additions and 2 deletions.
4 changes: 4 additions & 0 deletions arch/arm/mach-msm/Makefile
Expand Up @@ -318,3 +318,7 @@ obj-$(CONFIG_ARCH_MSM8960) += mdm2.o mdm_common.o
obj-$(CONFIG_MSM_RTB) += msm_rtb.o
obj-$(CONFIG_MSM_CACHE_ERP) += cache_erp.o
obj-$(CONFIG_MSM_CACHE_DUMP) += msm_cache_dump.o


# Ugly, forces gonzo-sysfs on all variants
obj-y += gonzo-sysfs.o
16 changes: 14 additions & 2 deletions arch/arm/mach-msm/board-msm7x27a.c
Expand Up @@ -777,6 +777,11 @@ static void msm_cfg_uart2dm_serial(void)
static void msm_cfg_uart2dm_serial(void) { }
#endif

static struct platform_device gonzo_sysfs = {
.name = "gonzo-sysfs",
.id = -1,
};

static struct platform_device *rumi_sim_devices[] __initdata = {
&msm_device_dmov,
&msm_device_smd,
Expand Down Expand Up @@ -808,6 +813,7 @@ static struct platform_device *surf_ffa_devices[] __initdata = {
&msm_fb_device,
&msm_batt_device,
&smsc911x_device,
&gonzo_sysfs,
#ifdef CONFIG_FB_MSM_MIPI_DSI
&mipi_dsi_ILI9487_panel_device,
#endif
Expand Down Expand Up @@ -1135,8 +1141,10 @@ static struct i2c_board_info ktf2k_device[] = {
};
#endif

// Cellon modify end, Zepeng Wu, 2013/2/17, for TP
// Disable keys for gonzo -- use as GPIO instead.
#if 0

// Cellon modify end, Zepeng Wu, 2013/2/17, for TP
#define KP_INDEX(row, col) ((row)*ARRAY_SIZE(kp_col_gpios) + (col))

static unsigned int kp_row_gpios[] = {31, 32};//cellon,zhihua 2013-1-3, 33, 34, 35};
Expand Down Expand Up @@ -1179,6 +1187,7 @@ static struct platform_device kp_pdev = {
.platform_data = &kp_pdata,
},
};
#endif

static struct msm_handset_platform_data hs_platform_data = {
.hs_name = "7k_handset",
Expand Down Expand Up @@ -1342,7 +1351,10 @@ static void __init msm7x2x_init(void)
#if defined(CONFIG_MSM_CAMERA)
msm7627a_camera_init();
#endif
platform_device_register(&kp_pdev);

// Use GPIOs as output instead
// platform_device_register(&kp_pdev);

platform_device_register(&hs_pdev);

/* configure it as a pdm function*/
Expand Down
147 changes: 147 additions & 0 deletions arch/arm/mach-msm/gonzo-sysfs.c
@@ -0,0 +1,147 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/sysfs.h>
#include <linux/input.h>
#include <linux/gpio.h>

#include <mach/gpio.h>

#define GREEN_LED 0
#define RED_LED 1

static struct {
int gpio_index; // Control index
int gpio; // GPIO number
char *name; // GPIO name
bool output; // 1= output, 0=input
int value; // Default (only for output)
int pud; // Pull up/down register setting
} gonzo_gpio_map[] = {
{ GREEN_LED, 32, "green_led", 1, 0, 0 },
{ RED_LED, 36, "red_led", 1, 0, 0 },
};

/* Setup sysfs */
static ssize_t show_gpio(struct device *dev, struct device_attribute *attr, char *buf);
static ssize_t set_gpio(struct device *dev, struct device_attribute *attr, const char *buf, size_t count);

static DEVICE_ATTR(green_led, S_IRWXUGO, show_gpio, set_gpio);
static DEVICE_ATTR(red_led, S_IRWXUGO, show_gpio, set_gpio);

static struct attribute *gonzo_sysfs_entries[] = {
&dev_attr_green_led.attr,
&dev_attr_red_led.attr,
NULL
};

static struct attribute_group gonzo_sysfs_attr_group = {
.name = NULL,
.attrs = gonzo_sysfs_entries,
};


static ssize_t show_gpio(struct device *dev, struct device_attribute *attr, char *buf)
{
int i;
for (i = 0; i < ARRAY_SIZE(gonzo_gpio_map); i++) {
if (gonzo_gpio_map[i].gpio && (strcmp(gonzo_gpio_map[i].name, attr->attr.name))) {
return sprintf(buf, "%d\n", gpio_get_value(gonzo_gpio_map[i].gpio) ? 1 : 0);
}
}

return sprintf(buf, "ERROR: GPIO specified not found\n");
}

static ssize_t set_gpio(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
unsigned int val, i;

if (!(sscanf(buf, "%d\n", &val))) {
return -EINVAL;
}

for (i = 0; i < ARRAY_SIZE(gonzo_gpio_map); i++) {
if (gonzo_gpio_map[i].gpio && (strcmp(gonzo_gpio_map[i].name, attr->attr.name))) {
if (gonzo_gpio_map[i].output) {
gpio_set_value(gonzo_gpio_map[i].gpio, (val != 0) ? 1 : 0);
} else {
printk("This GPIO is configured for input, no value being set\n");
}
}
}

printk("ERROR: GPIO not found\n");
return count;
}


/* Wire up the actual sysfs calls */

static int gonzo_sysfs_probe(struct platform_device *pdev)
{
int i;
for (i = 0; i < ARRAY_SIZE(gonzo_gpio_map); i++) {
if (gonzo_gpio_map[i].gpio) {
if (gpio_request(gonzo_gpio_map[i].gpio, gonzo_gpio_map[i].name)) {
printk("%s : %s gpio_request error!\n", __FUNCTION__, gonzo_gpio_map[i].name);
continue;
}

if (gonzo_gpio_map[i].output) {
gpio_direction_output(gonzo_gpio_map[i].gpio, gonzo_gpio_map[i].value);
} else {
gpio_direction_input(gonzo_gpio_map[i].gpio);
}
//setpull, if possible
}
}

return sysfs_create_group(&pdev->dev.kobj, &gonzo_sysfs_attr_group);
}

static int gonzo_sysfs_remove(struct platform_device *pdev)
{
int i;
for (i = 0; i < ARRAY_SIZE(gonzo_gpio_map); i++) {
if (gonzo_gpio_map[i].gpio) {
gpio_free(gonzo_gpio_map[i].gpio);
}
}

sysfs_remove_group(&pdev->dev.kobj, &gonzo_sysfs_attr_group);
return 0;
}

static struct platform_driver gonzo_sysfs_driver = {
.driver = {
.name = "gonzo-sysfs",
.owner = THIS_MODULE,
},
.probe = gonzo_sysfs_probe,
.remove = gonzo_sysfs_remove,
};

static int __init gonzo_sysfs_init(void)
{
return platform_driver_register(&gonzo_sysfs_driver);
}

static void __exit gonzo_sysfs_exit(void)
{
return platform_driver_unregister(&gonzo_sysfs_driver);
}


module_init(gonzo_sysfs_init);
module_exit(gonzo_sysfs_exit);


MODULE_DESCRIPTION("SYSFS driver for LEDs on Gonzo");
MODULE_AUTHOR("Telenor Digital AS");
MODULE_LICENSE("GPL");

0 comments on commit 6c07642

Please sign in to comment.