Loading arch/arm/mach-s3c2410/mach-bast.c +32 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ #include <mach/regs-mem.h> #include <mach/regs-lcd.h> #include <plat/hwmon.h> #include <plat/nand.h> #include <plat/iic.h> #include <mach/fb.h> Loading Loading @@ -547,7 +548,35 @@ static struct i2c_board_info bast_i2c_devs[] __initdata = { }, }; static struct s3c_hwmon_pdata bast_hwmon_info = { /* LCD contrast (0-6.6V) */ .in[0] = &(struct s3c_hwmon_chcfg) { .name = "lcd-contrast", .mult = 3300, .div = 512, }, /* LED current feedback */ .in[1] = &(struct s3c_hwmon_chcfg) { .name = "led-feedback", .mult = 3300, .div = 1024, }, /* LCD feedback (0-6.6V) */ .in[2] = &(struct s3c_hwmon_chcfg) { .name = "lcd-feedback", .mult = 3300, .div = 512, }, /* Vcore (1.8-2.0V), Vref 3.3V */ .in[3] = &(struct s3c_hwmon_chcfg) { .name = "vcore", .mult = 3300, .div = 1024, }, }; /* Standard BAST devices */ // cat /sys/devices/platform/s3c24xx-adc/s3c-hwmon/in_0 static struct platform_device *bast_devices[] __initdata = { &s3c_device_usb, Loading @@ -556,6 +585,8 @@ static struct platform_device *bast_devices[] __initdata = { &s3c_device_i2c0, &s3c_device_rtc, &s3c_device_nand, &s3c_device_adc, &s3c_device_hwmon, &bast_device_dm9k, &bast_device_asix, &bast_device_axpp, Loading Loading @@ -588,6 +619,7 @@ static void __init bast_map_io(void) s3c24xx_register_clocks(bast_clocks, ARRAY_SIZE(bast_clocks)); s3c_device_nand.dev.platform_data = &bast_nand_info; s3c_device_hwmon.dev.platform_data = &bast_hwmon_info; s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc)); s3c24xx_init_clocks(0); Loading arch/arm/plat-s3c/include/plat/adc.h +6 −2 Original line number Diff line number Diff line Loading @@ -19,10 +19,14 @@ struct s3c_adc_client; extern int s3c_adc_start(struct s3c_adc_client *client, unsigned int channel, unsigned int nr_samples); extern int s3c_adc_read(struct s3c_adc_client *client, unsigned int ch); extern struct s3c_adc_client * s3c_adc_register(struct platform_device *pdev, void (*select)(unsigned selected), void (*conv)(unsigned d0, unsigned d1, void (*select)(struct s3c_adc_client *client, unsigned selected), void (*conv)(struct s3c_adc_client *client, unsigned d0, unsigned d1, unsigned *samples_left), unsigned int is_ts); Loading arch/arm/plat-s3c/include/plat/devs.h +2 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,8 @@ extern struct platform_device s3c_device_hsmmc2; extern struct platform_device s3c_device_spi0; extern struct platform_device s3c_device_spi1; extern struct platform_device s3c_device_hwmon; extern struct platform_device s3c_device_nand; extern struct platform_device s3c_device_usbgadget; Loading arch/arm/plat-s3c/include/plat/hwmon.h 0 → 100644 +41 −0 Original line number Diff line number Diff line /* linux/arch/arm/plat-s3c/include/plat/hwmon.h * * Copyright 2005 Simtec Electronics * Ben Dooks <ben@simtec.co.uk> * http://armlinux.simtec.co.uk/ * * S3C - HWMon interface for ADC * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #ifndef __ASM_ARCH_ADC_HWMON_H #define __ASM_ARCH_ADC_HWMON_H __FILE__ /** * s3c_hwmon_chcfg - channel configuration * @name: The name to give this channel. * @mult: Multiply the ADC value read by this. * @div: Divide the value from the ADC by this. * * The value read from the ADC is converted to a value that * hwmon expects (mV) by result = (value_read * @mult) / @div. */ struct s3c_hwmon_chcfg { const char *name; unsigned int mult; unsigned int div; }; /** * s3c_hwmon_pdata - HWMON platform data * @in: One configuration for each possible channel used. */ struct s3c_hwmon_pdata { struct s3c_hwmon_chcfg *in[8]; }; #endif /* __ASM_ARCH_ADC_HWMON_H */ arch/arm/plat-s3c24xx/adc.c +53 −11 Original line number Diff line number Diff line Loading @@ -39,13 +39,16 @@ struct s3c_adc_client { struct platform_device *pdev; struct list_head pend; wait_queue_head_t *wait; unsigned int nr_samples; int result; unsigned char is_ts; unsigned char channel; void (*select_cb)(unsigned selected); void (*convert_cb)(unsigned val1, unsigned val2, void (*select_cb)(struct s3c_adc_client *c, unsigned selected); void (*convert_cb)(struct s3c_adc_client *c, unsigned val1, unsigned val2, unsigned *samples_left); }; Loading Loading @@ -81,7 +84,7 @@ static inline void s3c_adc_select(struct adc_device *adc, { unsigned con = readl(adc->regs + S3C2410_ADCCON); client->select_cb(1); client->select_cb(client, 1); con &= ~S3C2410_ADCCON_MUXMASK; con &= ~S3C2410_ADCCON_STDBM; Loading Loading @@ -153,25 +156,61 @@ int s3c_adc_start(struct s3c_adc_client *client, } EXPORT_SYMBOL_GPL(s3c_adc_start); static void s3c_adc_default_select(unsigned select) static void s3c_convert_done(struct s3c_adc_client *client, unsigned v, unsigned u, unsigned *left) { client->result = v; wake_up(client->wait); } int s3c_adc_read(struct s3c_adc_client *client, unsigned int ch) { DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wake); int ret; client->convert_cb = s3c_convert_done; client->wait = &wake; client->result = -1; ret = s3c_adc_start(client, ch, 1); if (ret < 0) goto err; ret = wait_event_timeout(wake, client->result >= 0, HZ / 2); if (client->result < 0) { ret = -ETIMEDOUT; goto err; } client->convert_cb = NULL; return client->result; err: return ret; } EXPORT_SYMBOL_GPL(s3c_adc_convert); static void s3c_adc_default_select(struct s3c_adc_client *client, unsigned select) { } struct s3c_adc_client *s3c_adc_register(struct platform_device *pdev, void (*select)(unsigned int selected), void (*conv)(unsigned d0, unsigned d1, void (*select)(struct s3c_adc_client *client, unsigned int selected), void (*conv)(struct s3c_adc_client *client, unsigned d0, unsigned d1, unsigned *samples_left), unsigned int is_ts) { struct s3c_adc_client *client; WARN_ON(!pdev); WARN_ON(!conv); if (!select) select = s3c_adc_default_select; if (!conv || !pdev) if (!pdev) return ERR_PTR(-EINVAL); client = kzalloc(sizeof(struct s3c_adc_client), GFP_KERNEL); Loading Loading @@ -230,16 +269,19 @@ static irqreturn_t s3c_adc_irq(int irq, void *pw) adc_dbg(adc, "read %d: 0x%04x, 0x%04x\n", client->nr_samples, data0, data1); client->nr_samples--; (client->convert_cb)(data0 & 0x3ff, data1 & 0x3ff, &client->nr_samples); if (client->convert_cb) (client->convert_cb)(client, data0 & 0x3ff, data1 & 0x3ff, &client->nr_samples); if (client->nr_samples > 0) { /* fire another conversion for this */ client->select_cb(1); client->select_cb(client, 1); s3c_adc_convert(adc); } else { local_irq_save(flags); (client->select_cb)(0); (client->select_cb)(client, 0); adc->cur = NULL; s3c_adc_try(adc); Loading Loading
arch/arm/mach-s3c2410/mach-bast.c +32 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ #include <mach/regs-mem.h> #include <mach/regs-lcd.h> #include <plat/hwmon.h> #include <plat/nand.h> #include <plat/iic.h> #include <mach/fb.h> Loading Loading @@ -547,7 +548,35 @@ static struct i2c_board_info bast_i2c_devs[] __initdata = { }, }; static struct s3c_hwmon_pdata bast_hwmon_info = { /* LCD contrast (0-6.6V) */ .in[0] = &(struct s3c_hwmon_chcfg) { .name = "lcd-contrast", .mult = 3300, .div = 512, }, /* LED current feedback */ .in[1] = &(struct s3c_hwmon_chcfg) { .name = "led-feedback", .mult = 3300, .div = 1024, }, /* LCD feedback (0-6.6V) */ .in[2] = &(struct s3c_hwmon_chcfg) { .name = "lcd-feedback", .mult = 3300, .div = 512, }, /* Vcore (1.8-2.0V), Vref 3.3V */ .in[3] = &(struct s3c_hwmon_chcfg) { .name = "vcore", .mult = 3300, .div = 1024, }, }; /* Standard BAST devices */ // cat /sys/devices/platform/s3c24xx-adc/s3c-hwmon/in_0 static struct platform_device *bast_devices[] __initdata = { &s3c_device_usb, Loading @@ -556,6 +585,8 @@ static struct platform_device *bast_devices[] __initdata = { &s3c_device_i2c0, &s3c_device_rtc, &s3c_device_nand, &s3c_device_adc, &s3c_device_hwmon, &bast_device_dm9k, &bast_device_asix, &bast_device_axpp, Loading Loading @@ -588,6 +619,7 @@ static void __init bast_map_io(void) s3c24xx_register_clocks(bast_clocks, ARRAY_SIZE(bast_clocks)); s3c_device_nand.dev.platform_data = &bast_nand_info; s3c_device_hwmon.dev.platform_data = &bast_hwmon_info; s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc)); s3c24xx_init_clocks(0); Loading
arch/arm/plat-s3c/include/plat/adc.h +6 −2 Original line number Diff line number Diff line Loading @@ -19,10 +19,14 @@ struct s3c_adc_client; extern int s3c_adc_start(struct s3c_adc_client *client, unsigned int channel, unsigned int nr_samples); extern int s3c_adc_read(struct s3c_adc_client *client, unsigned int ch); extern struct s3c_adc_client * s3c_adc_register(struct platform_device *pdev, void (*select)(unsigned selected), void (*conv)(unsigned d0, unsigned d1, void (*select)(struct s3c_adc_client *client, unsigned selected), void (*conv)(struct s3c_adc_client *client, unsigned d0, unsigned d1, unsigned *samples_left), unsigned int is_ts); Loading
arch/arm/plat-s3c/include/plat/devs.h +2 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,8 @@ extern struct platform_device s3c_device_hsmmc2; extern struct platform_device s3c_device_spi0; extern struct platform_device s3c_device_spi1; extern struct platform_device s3c_device_hwmon; extern struct platform_device s3c_device_nand; extern struct platform_device s3c_device_usbgadget; Loading
arch/arm/plat-s3c/include/plat/hwmon.h 0 → 100644 +41 −0 Original line number Diff line number Diff line /* linux/arch/arm/plat-s3c/include/plat/hwmon.h * * Copyright 2005 Simtec Electronics * Ben Dooks <ben@simtec.co.uk> * http://armlinux.simtec.co.uk/ * * S3C - HWMon interface for ADC * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #ifndef __ASM_ARCH_ADC_HWMON_H #define __ASM_ARCH_ADC_HWMON_H __FILE__ /** * s3c_hwmon_chcfg - channel configuration * @name: The name to give this channel. * @mult: Multiply the ADC value read by this. * @div: Divide the value from the ADC by this. * * The value read from the ADC is converted to a value that * hwmon expects (mV) by result = (value_read * @mult) / @div. */ struct s3c_hwmon_chcfg { const char *name; unsigned int mult; unsigned int div; }; /** * s3c_hwmon_pdata - HWMON platform data * @in: One configuration for each possible channel used. */ struct s3c_hwmon_pdata { struct s3c_hwmon_chcfg *in[8]; }; #endif /* __ASM_ARCH_ADC_HWMON_H */
arch/arm/plat-s3c24xx/adc.c +53 −11 Original line number Diff line number Diff line Loading @@ -39,13 +39,16 @@ struct s3c_adc_client { struct platform_device *pdev; struct list_head pend; wait_queue_head_t *wait; unsigned int nr_samples; int result; unsigned char is_ts; unsigned char channel; void (*select_cb)(unsigned selected); void (*convert_cb)(unsigned val1, unsigned val2, void (*select_cb)(struct s3c_adc_client *c, unsigned selected); void (*convert_cb)(struct s3c_adc_client *c, unsigned val1, unsigned val2, unsigned *samples_left); }; Loading Loading @@ -81,7 +84,7 @@ static inline void s3c_adc_select(struct adc_device *adc, { unsigned con = readl(adc->regs + S3C2410_ADCCON); client->select_cb(1); client->select_cb(client, 1); con &= ~S3C2410_ADCCON_MUXMASK; con &= ~S3C2410_ADCCON_STDBM; Loading Loading @@ -153,25 +156,61 @@ int s3c_adc_start(struct s3c_adc_client *client, } EXPORT_SYMBOL_GPL(s3c_adc_start); static void s3c_adc_default_select(unsigned select) static void s3c_convert_done(struct s3c_adc_client *client, unsigned v, unsigned u, unsigned *left) { client->result = v; wake_up(client->wait); } int s3c_adc_read(struct s3c_adc_client *client, unsigned int ch) { DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wake); int ret; client->convert_cb = s3c_convert_done; client->wait = &wake; client->result = -1; ret = s3c_adc_start(client, ch, 1); if (ret < 0) goto err; ret = wait_event_timeout(wake, client->result >= 0, HZ / 2); if (client->result < 0) { ret = -ETIMEDOUT; goto err; } client->convert_cb = NULL; return client->result; err: return ret; } EXPORT_SYMBOL_GPL(s3c_adc_convert); static void s3c_adc_default_select(struct s3c_adc_client *client, unsigned select) { } struct s3c_adc_client *s3c_adc_register(struct platform_device *pdev, void (*select)(unsigned int selected), void (*conv)(unsigned d0, unsigned d1, void (*select)(struct s3c_adc_client *client, unsigned int selected), void (*conv)(struct s3c_adc_client *client, unsigned d0, unsigned d1, unsigned *samples_left), unsigned int is_ts) { struct s3c_adc_client *client; WARN_ON(!pdev); WARN_ON(!conv); if (!select) select = s3c_adc_default_select; if (!conv || !pdev) if (!pdev) return ERR_PTR(-EINVAL); client = kzalloc(sizeof(struct s3c_adc_client), GFP_KERNEL); Loading Loading @@ -230,16 +269,19 @@ static irqreturn_t s3c_adc_irq(int irq, void *pw) adc_dbg(adc, "read %d: 0x%04x, 0x%04x\n", client->nr_samples, data0, data1); client->nr_samples--; (client->convert_cb)(data0 & 0x3ff, data1 & 0x3ff, &client->nr_samples); if (client->convert_cb) (client->convert_cb)(client, data0 & 0x3ff, data1 & 0x3ff, &client->nr_samples); if (client->nr_samples > 0) { /* fire another conversion for this */ client->select_cb(1); client->select_cb(client, 1); s3c_adc_convert(adc); } else { local_irq_save(flags); (client->select_cb)(0); (client->select_cb)(client, 0); adc->cur = NULL; s3c_adc_try(adc); Loading