Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 63c949ea authored by Ben Dooks's avatar Ben Dooks
Browse files

Merge branch 'next-s3c-hwmon' into next-s3c

parents 9b71de49 bff78650
Loading
Loading
Loading
Loading
+32 −0
Original line number Diff line number Diff line
@@ -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>
@@ -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,
@@ -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,
@@ -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);
+6 −2
Original line number Diff line number Diff line
@@ -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);

+2 −0
Original line number Diff line number Diff line
@@ -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;
+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 */
+53 −11
Original line number Diff line number Diff line
@@ -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);
};

@@ -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;
@@ -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);
@@ -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