// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * max6639.c - Support for Maxim MAX6639
 *
 * 2-Channel Temperature Monitor with Dual PWM Fan-Speed Controller
 *
 * Copyright (C) 2010, 2011 Roland Stigge <stigge@antcom.de>
 *
 * based on the initial MAX6639 support from semptian.net
 * by He Changqing <hechangqing@semptian.com>
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <linux/platform_data/max6639.h>
#include <linux/regmap.h>
#include <linux/util_macros.h>

/* Addresses to scan */
static const unsigned short normal_i2c[] = { 0x2c, 0x2e, 0x2f, I2C_CLIENT_END };

/* The MAX6639 registers, valid channel numbers: 0, 1 */
#define MAX6639_REG_TEMP(ch)			(0x00 + (ch))
#define MAX6639_REG_STATUS			0x02
#define MAX6639_REG_OUTPUT_MASK			0x03
#define MAX6639_REG_GCONFIG			0x04
#define MAX6639_REG_TEMP_EXT(ch)		(0x05 + (ch))
#define MAX6639_REG_ALERT_LIMIT(ch)		(0x08 + (ch))
#define MAX6639_REG_OT_LIMIT(ch)		(0x0A + (ch))
#define MAX6639_REG_THERM_LIMIT(ch)		(0x0C + (ch))
#define MAX6639_REG_FAN_CONFIG1(ch)		(0x10 + (ch) * 4)
#define MAX6639_REG_FAN_CONFIG2a(ch)		(0x11 + (ch) * 4)
#define MAX6639_REG_FAN_CONFIG2b(ch)		(0x12 + (ch) * 4)
#define MAX6639_REG_FAN_CONFIG3(ch)		(0x13 + (ch) * 4)
#define MAX6639_REG_FAN_CNT(ch)			(0x20 + (ch))
#define MAX6639_REG_TARGET_CNT(ch)		(0x22 + (ch))
#define MAX6639_REG_FAN_PPR(ch)			(0x24 + (ch))
#define MAX6639_REG_TARGTDUTY(ch)		(0x26 + (ch))
#define MAX6639_REG_FAN_START_TEMP(ch)		(0x28 + (ch))
#define MAX6639_REG_DEVID			0x3D
#define MAX6639_REG_MANUID			0x3E
#define MAX6639_REG_DEVREV			0x3F

/* Register bits */
#define MAX6639_GCONFIG_STANDBY			0x80
#define MAX6639_GCONFIG_POR			0x40
#define MAX6639_GCONFIG_DISABLE_TIMEOUT		0x20
#define MAX6639_GCONFIG_CH2_LOCAL		0x10
#define MAX6639_GCONFIG_PWM_FREQ_HI		0x08

#define MAX6639_FAN_CONFIG1_PWM			0x80
#define MAX6639_FAN_CONFIG3_FREQ_MASK		0x03
#define MAX6639_FAN_CONFIG3_THERM_FULL_SPEED	0x40

#define MAX6639_NUM_CHANNELS			2

static const int rpm_ranges[] = { 2000, 4000, 8000, 16000 };

/* Supported PWM frequency */
static const unsigned int freq_table[] = { 20, 33, 50, 100, 5000, 8333, 12500,
					   25000 };

#define FAN_FROM_REG(val, rpm_range)	((val) == 0 || (val) == 255 ? \
				0 : (rpm_ranges[rpm_range] * 30) / (val))
#define TEMP_LIMIT_TO_REG(val)	clamp_val((val) / 1000, 0, 255)

/*
 * Client data (each client gets its own)
 */
struct max6639_data {
	struct regmap *regmap;
	struct mutex update_lock;

	/* Register values initialized only once */
	u8 ppr[MAX6639_NUM_CHANNELS];	/* Pulses per rotation 0..3 for 1..4 ppr */
	u8 rpm_range[MAX6639_NUM_CHANNELS]; /* Index in above rpm_ranges table */

	/* Optional regulator for FAN supply */
	struct regulator *reg;
};

static int max6639_temp_read_input(struct device *dev, int channel, long *temp)
{
	u32 regs[2] = { MAX6639_REG_TEMP_EXT(channel), MAX6639_REG_TEMP(channel) };
	struct max6639_data *data = dev_get_drvdata(dev);
	u8 regvals[2];
	int res;

	res = regmap_multi_reg_read(data->regmap, regs, regvals, 2);
	if (res < 0)
		return res;

	*temp = ((regvals[0] >> 5) | (regvals[1] << 3)) * 125;

	return 0;
}

static int max6639_temp_read_fault(struct device *dev, int channel, long *fault)
{
	struct max6639_data *data = dev_get_drvdata(dev);
	unsigned int val;
	int res;

	res = regmap_read(data->regmap, MAX6639_REG_TEMP_EXT(channel), &val);
	if (res < 0)
		return res;

	*fault = val & 1;

	return 0;
}

static int max6639_temp_read_max(struct device *dev, int channel, long *max)
{
	struct max6639_data *data = dev_get_drvdata(dev);
	unsigned int val;
	int res;

	res = regmap_read(data->regmap, MAX6639_REG_THERM_LIMIT(channel), &val);
	if (res < 0)
		return res;

	*max = (long)val * 1000;

	return 0;
}

static int max6639_temp_read_crit(struct device *dev, int channel, long *crit)
{
	struct max6639_data *data = dev_get_drvdata(dev);
	unsigned int val;
	int res;

	res = regmap_read(data->regmap, MAX6639_REG_ALERT_LIMIT(channel), &val);
	if (res < 0)
		return res;

	*crit = (long)val * 1000;

	return 0;
}

static int max6639_temp_read_emergency(struct device *dev, int channel, long *emerg)
{
	struct max6639_data *data = dev_get_drvdata(dev);
	unsigned int val;
	int res;

	res = regmap_read(data->regmap, MAX6639_REG_OT_LIMIT(channel), &val);
	if (res < 0)
		return res;

	*emerg = (long)val * 1000;

	return 0;
}

static int max6639_get_status(struct device *dev, unsigned int *status)
{
	struct max6639_data *data = dev_get_drvdata(dev);
	unsigned int val;
	int res;

	res = regmap_read(data->regmap, MAX6639_REG_STATUS, &val);
	if (res < 0)
		return res;

	*status = val;

	return 0;
}

static int max6639_temp_set_max(struct max6639_data *data, int channel, long val)
{
	int res;

	res = regmap_write(data->regmap, MAX6639_REG_THERM_LIMIT(channel),
			   TEMP_LIMIT_TO_REG(val));
	return res;
}

static int max6639_temp_set_crit(struct max6639_data *data, int channel, long val)
{
	int res;

	res = regmap_write(data->regmap, MAX6639_REG_ALERT_LIMIT(channel), TEMP_LIMIT_TO_REG(val));

	return res;
}

static int max6639_temp_set_emergency(struct max6639_data *data, int channel, long val)
{
	int res;

	res = regmap_write(data->regmap, MAX6639_REG_OT_LIMIT(channel), TEMP_LIMIT_TO_REG(val));

	return res;
}

static int max6639_read_fan(struct device *dev, u32 attr, int channel,
			    long *fan_val)
{
	struct max6639_data *data = dev_get_drvdata(dev);
	unsigned int val;
	int res;

	switch (attr) {
	case hwmon_fan_input:
		res = regmap_read(data->regmap, MAX6639_REG_FAN_CNT(channel), &val);
		if (res < 0)
			return res;
		*fan_val = FAN_FROM_REG(val, data->rpm_range[channel]);
		return 0;
	case hwmon_fan_fault:
		res = max6639_get_status(dev, &val);
		if (res < 0)
			return res;
		*fan_val = !!(val & BIT(1 - channel));
		return 0;
	case hwmon_fan_pulses:
		*fan_val = data->ppr[channel];
		return 0;
	default:
		return -EOPNOTSUPP;
	}
}

static int max6639_set_ppr(struct max6639_data *data, int channel, u8 ppr)
{
	/* Decrement the PPR value and shift left by 6 to match the register format */
	return regmap_write(data->regmap, MAX6639_REG_FAN_PPR(channel), ppr-- << 6);
}

static int max6639_write_fan(struct device *dev, u32 attr, int channel,
			     long val)
{
	struct max6639_data *data = dev_get_drvdata(dev);
	int err;

	switch (attr) {
	case hwmon_fan_pulses:
		if (val <= 0 || val > 4)
			return -EINVAL;

		mutex_lock(&data->update_lock);
		/* Set Fan pulse per revolution */
		err = max6639_set_ppr(data, channel, val);
		if (err < 0) {
			mutex_unlock(&data->update_lock);
			return err;
		}
		data->ppr[channel] = val;

		mutex_unlock(&data->update_lock);
		return 0;
	default:
		return -EOPNOTSUPP;
	}
}

static umode_t max6639_fan_is_visible(const void *_data, u32 attr, int channel)
{
	switch (attr) {
	case hwmon_fan_input:
	case hwmon_fan_fault:
		return 0444;
	case hwmon_fan_pulses:
		return 0644;
	default:
		return 0;
	}
}

static int max6639_read_pwm(struct device *dev, u32 attr, int channel,
			    long *pwm_val)
{
	u32 regs[2] = { MAX6639_REG_FAN_CONFIG3(channel), MAX6639_REG_GCONFIG };
	struct max6639_data *data = dev_get_drvdata(dev);
	unsigned int val;
	u8 regvals[2];
	int res;
	u8 i;

	switch (attr) {
	case hwmon_pwm_input:
		res = regmap_read(data->regmap, MAX6639_REG_TARGTDUTY(channel), &val);
		if (res < 0)
			return res;
		*pwm_val = val * 255 / 120;
		return 0;
	case hwmon_pwm_freq:
		res = regmap_multi_reg_read(data->regmap, regs, regvals, 2);
		if (res < 0)
			return res;
		i = regvals[0] & MAX6639_FAN_CONFIG3_FREQ_MASK;
		if (regvals[1] & MAX6639_GCONFIG_PWM_FREQ_HI)
			i |= 0x4;
		*pwm_val = freq_table[i];
		return 0;
	default:
		return -EOPNOTSUPP;
	}
}

static int max6639_write_pwm(struct device *dev, u32 attr, int channel,
			     long val)
{
	struct max6639_data *data = dev_get_drvdata(dev);
	int err;
	u8 i;

	switch (attr) {
	case hwmon_pwm_input:
		if (val < 0 || val > 255)
			return -EINVAL;
		err = regmap_write(data->regmap, MAX6639_REG_TARGTDUTY(channel),
				   val * 120 / 255);
		return err;
	case hwmon_pwm_freq:
		val = clamp_val(val, 0, 25000);

		i = find_closest(val, freq_table, ARRAY_SIZE(freq_table));

		mutex_lock(&data->update_lock);
		err = regmap_update_bits(data->regmap, MAX6639_REG_FAN_CONFIG3(channel),
					 MAX6639_FAN_CONFIG3_FREQ_MASK, i);
		if (err < 0) {
			mutex_unlock(&data->update_lock);
			return err;
		}

		if (i >> 2)
			err = regmap_set_bits(data->regmap, MAX6639_REG_GCONFIG,
					      MAX6639_GCONFIG_PWM_FREQ_HI);
		else
			err = regmap_clear_bits(data->regmap, MAX6639_REG_GCONFIG,
						MAX6639_GCONFIG_PWM_FREQ_HI);

		mutex_unlock(&data->update_lock);
		return err;
	default:
		return -EOPNOTSUPP;
	}
}

static umode_t max6639_pwm_is_visible(const void *_data, u32 attr, int channel)
{
	switch (attr) {
	case hwmon_pwm_input:
	case hwmon_pwm_freq:
		return 0644;
	default:
		return 0;
	}
}

static int max6639_read_temp(struct device *dev, u32 attr, int channel,
			     long *val)
{
	unsigned int status;
	int res;

	switch (attr) {
	case hwmon_temp_input:
		res = max6639_temp_read_input(dev, channel, val);
		return res;
	case hwmon_temp_fault:
		res = max6639_temp_read_fault(dev, channel, val);
		return res;
	case hwmon_temp_max:
		res = max6639_temp_read_max(dev, channel, val);
		return res;
	case hwmon_temp_crit:
		res = max6639_temp_read_crit(dev, channel, val);
		return res;
	case hwmon_temp_emergency:
		res = max6639_temp_read_emergency(dev, channel, val);
		return res;
	case hwmon_temp_max_alarm:
		res = max6639_get_status(dev, &status);
		if (res < 0)
			return res;
		*val = !!(status & BIT(3 - channel));
		return 0;
	case hwmon_temp_crit_alarm:
		res = max6639_get_status(dev, &status);
		if (res < 0)
			return res;
		*val = !!(status & BIT(7 - channel));
		return 0;
	case hwmon_temp_emergency_alarm:
		res = max6639_get_status(dev, &status);
		if (res < 0)
			return res;
		*val = !!(status & BIT(5 - channel));
		return 0;
	default:
		return -EOPNOTSUPP;
	}
}

static int max6639_write_temp(struct device *dev, u32 attr, int channel,
			      long val)
{
	struct max6639_data *data = dev_get_drvdata(dev);

	switch (attr) {
	case hwmon_temp_max:
		return max6639_temp_set_max(data, channel, val);
	case hwmon_temp_crit:
		return max6639_temp_set_crit(data, channel, val);
	case hwmon_temp_emergency:
		return max6639_temp_set_emergency(data, channel, val);
	default:
		return -EOPNOTSUPP;
	}
}

static umode_t max6639_temp_is_visible(const void *_data, u32 attr, int channel)
{
	switch (attr) {
	case hwmon_temp_input:
	case hwmon_temp_fault:
	case hwmon_temp_max_alarm:
	case hwmon_temp_crit_alarm:
	case hwmon_temp_emergency_alarm:
		return 0444;
	case hwmon_temp_max:
	case hwmon_temp_crit:
	case hwmon_temp_emergency:
		return 0644;
	default:
		return 0;
	}
}

static int max6639_read(struct device *dev, enum hwmon_sensor_types type,
			u32 attr, int channel, long *val)
{
	switch (type) {
	case hwmon_fan:
		return max6639_read_fan(dev, attr, channel, val);
	case hwmon_pwm:
		return max6639_read_pwm(dev, attr, channel, val);
	case hwmon_temp:
		return max6639_read_temp(dev, attr, channel, val);
	default:
		return -EOPNOTSUPP;
	}
}

static int max6639_write(struct device *dev, enum hwmon_sensor_types type,
			 u32 attr, int channel, long val)
{
	switch (type) {
	case hwmon_fan:
		return max6639_write_fan(dev, attr, channel, val);
	case hwmon_pwm:
		return max6639_write_pwm(dev, attr, channel, val);
	case hwmon_temp:
		return max6639_write_temp(dev, attr, channel, val);
	default:
		return -EOPNOTSUPP;
	}
}

static umode_t max6639_is_visible(const void *data,
				  enum hwmon_sensor_types type,
				  u32 attr, int channel)
{
	switch (type) {
	case hwmon_fan:
		return max6639_fan_is_visible(data, attr, channel);
	case hwmon_pwm:
		return max6639_pwm_is_visible(data, attr, channel);
	case hwmon_temp:
		return max6639_temp_is_visible(data, attr, channel);
	default:
		return 0;
	}
}

static const struct hwmon_channel_info * const max6639_info[] = {
	HWMON_CHANNEL_INFO(fan,
			   HWMON_F_INPUT | HWMON_F_FAULT | HWMON_F_PULSES,
			   HWMON_F_INPUT | HWMON_F_FAULT | HWMON_F_PULSES),
	HWMON_CHANNEL_INFO(pwm,
			   HWMON_PWM_INPUT | HWMON_PWM_FREQ,
			   HWMON_PWM_INPUT | HWMON_PWM_FREQ),
	HWMON_CHANNEL_INFO(temp,
			   HWMON_T_INPUT | HWMON_T_FAULT | HWMON_T_MAX | HWMON_T_MAX_ALARM |
			   HWMON_T_CRIT | HWMON_T_CRIT_ALARM | HWMON_T_EMERGENCY |
			   HWMON_T_EMERGENCY_ALARM,
			   HWMON_T_INPUT | HWMON_T_FAULT | HWMON_T_MAX | HWMON_T_MAX_ALARM |
			   HWMON_T_CRIT | HWMON_T_CRIT_ALARM | HWMON_T_EMERGENCY |
			   HWMON_T_EMERGENCY_ALARM),
	NULL
};

static const struct hwmon_ops max6639_hwmon_ops = {
	.is_visible = max6639_is_visible,
	.read = max6639_read,
	.write = max6639_write,
};

static const struct hwmon_chip_info max6639_chip_info = {
	.ops = &max6639_hwmon_ops,
	.info = max6639_info,
};

/*
 *  returns respective index in rpm_ranges table
 *  1 by default on invalid range
 */
static int rpm_range_to_reg(int range)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(rpm_ranges); i++) {
		if (rpm_ranges[i] == range)
			return i;
	}

	return 1; /* default: 4000 RPM */
}

static int max6639_init_client(struct i2c_client *client,
			       struct max6639_data *data)
{
	struct max6639_platform_data *max6639_info =
		dev_get_platdata(&client->dev);
	int i;
	int rpm_range = 1; /* default: 4000 RPM */
	int err, ppr;

	/* Reset chip to default values, see below for GCONFIG setup */
	err = regmap_write(data->regmap, MAX6639_REG_GCONFIG, MAX6639_GCONFIG_POR);
	if (err)
		return err;

	/* Fans pulse per revolution is 2 by default */
	if (max6639_info && max6639_info->ppr > 0 &&
			max6639_info->ppr < 5)
		ppr = max6639_info->ppr;
	else
		ppr = 2;

	data->ppr[0] = ppr;
	data->ppr[1] = ppr;

	if (max6639_info)
		rpm_range = rpm_range_to_reg(max6639_info->rpm_range);
	data->rpm_range[0] = rpm_range;
	data->rpm_range[1] = rpm_range;

	for (i = 0; i < MAX6639_NUM_CHANNELS; i++) {
		/* Set Fan pulse per revolution */
		err = max6639_set_ppr(data, i, data->ppr[i]);
		if (err)
			return err;

		/* Fans config PWM, RPM */
		err = regmap_write(data->regmap, MAX6639_REG_FAN_CONFIG1(i),
				   MAX6639_FAN_CONFIG1_PWM | data->rpm_range[i]);
		if (err)
			return err;

		/* Fans PWM polarity high by default */
		if (max6639_info) {
			if (max6639_info->pwm_polarity == 0)
				err = regmap_write(data->regmap, MAX6639_REG_FAN_CONFIG2a(i), 0x00);
			else
				err = regmap_write(data->regmap, MAX6639_REG_FAN_CONFIG2a(i), 0x02);
		}
		if (err)
			return err;

		/*
		 * /THERM full speed enable,
		 * PWM frequency 25kHz, see also GCONFIG below
		 */
		err = regmap_write(data->regmap, MAX6639_REG_FAN_CONFIG3(i),
				   MAX6639_FAN_CONFIG3_THERM_FULL_SPEED | 0x03);
		if (err)
			return err;

		/* Max. temp. 80C/90C/100C */
		err = regmap_write(data->regmap, MAX6639_REG_THERM_LIMIT(i), 80);
		if (err)
			return err;
		err = regmap_write(data->regmap, MAX6639_REG_ALERT_LIMIT(i), 90);
		if (err)
			return err;
		err = regmap_write(data->regmap, MAX6639_REG_OT_LIMIT(i), 100);
		if (err)
			return err;

		/* PWM 120/120 (i.e. 100%) */
		err = regmap_write(data->regmap, MAX6639_REG_TARGTDUTY(i), 120);
		if (err)
			return err;
	}
	/* Start monitoring */
	return regmap_write(data->regmap, MAX6639_REG_GCONFIG,
			    MAX6639_GCONFIG_DISABLE_TIMEOUT | MAX6639_GCONFIG_CH2_LOCAL |
			    MAX6639_GCONFIG_PWM_FREQ_HI);

}

/* Return 0 if detection is successful, -ENODEV otherwise */
static int max6639_detect(struct i2c_client *client,
			  struct i2c_board_info *info)
{
	struct i2c_adapter *adapter = client->adapter;
	int dev_id, manu_id;

	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
		return -ENODEV;

	/* Actual detection via device and manufacturer ID */
	dev_id = i2c_smbus_read_byte_data(client, MAX6639_REG_DEVID);
	manu_id = i2c_smbus_read_byte_data(client, MAX6639_REG_MANUID);
	if (dev_id != 0x58 || manu_id != 0x4D)
		return -ENODEV;

	strscpy(info->type, "max6639", I2C_NAME_SIZE);

	return 0;
}

static void max6639_regulator_disable(void *data)
{
	regulator_disable(data);
}

static bool max6639_regmap_is_volatile(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case MAX6639_REG_TEMP(0):
	case MAX6639_REG_TEMP_EXT(0):
	case MAX6639_REG_TEMP(1):
	case MAX6639_REG_TEMP_EXT(1):
	case MAX6639_REG_STATUS:
	case MAX6639_REG_FAN_CNT(0):
	case MAX6639_REG_FAN_CNT(1):
	case MAX6639_REG_TARGTDUTY(0):
	case MAX6639_REG_TARGTDUTY(1):
		return true;
	default:
		return false;
	}
}

static const struct regmap_config max6639_regmap_config = {
	.reg_bits = 8,
	.val_bits = 8,
	.max_register = MAX6639_REG_DEVREV,
	.cache_type = REGCACHE_MAPLE,
	.volatile_reg = max6639_regmap_is_volatile,
};

static int max6639_probe(struct i2c_client *client)
{
	struct device *dev = &client->dev;
	struct max6639_data *data;
	struct device *hwmon_dev;
	int err;

	data = devm_kzalloc(dev, sizeof(struct max6639_data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	data->regmap = devm_regmap_init_i2c(client, &max6639_regmap_config);
	if (IS_ERR(data->regmap))
		return dev_err_probe(dev,
				     PTR_ERR(data->regmap),
				     "regmap initialization failed\n");

	data->reg = devm_regulator_get_optional(dev, "fan");
	if (IS_ERR(data->reg)) {
		if (PTR_ERR(data->reg) != -ENODEV)
			return PTR_ERR(data->reg);

		data->reg = NULL;
	} else {
		/* Spin up fans */
		err = regulator_enable(data->reg);
		if (err) {
			dev_err(dev, "Failed to enable fan supply: %d\n", err);
			return err;
		}
		err = devm_add_action_or_reset(dev, max6639_regulator_disable,
					       data->reg);
		if (err) {
			dev_err(dev, "Failed to register action: %d\n", err);
			return err;
		}
	}

	mutex_init(&data->update_lock);

	/* Initialize the max6639 chip */
	err = max6639_init_client(client, data);
	if (err < 0)
		return err;

	hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name,
							 data, &max6639_chip_info,
							 NULL);

	return PTR_ERR_OR_ZERO(hwmon_dev);
}

static int max6639_suspend(struct device *dev)
{
	struct max6639_data *data = dev_get_drvdata(dev);

	if (data->reg)
		regulator_disable(data->reg);

	return regmap_write_bits(data->regmap, MAX6639_REG_GCONFIG, MAX6639_GCONFIG_STANDBY,
				 MAX6639_GCONFIG_STANDBY);
}

static int max6639_resume(struct device *dev)
{
	struct max6639_data *data = dev_get_drvdata(dev);
	int ret;

	if (data->reg) {
		ret = regulator_enable(data->reg);
		if (ret) {
			dev_err(dev, "Failed to enable fan supply: %d\n", ret);
			return ret;
		}
	}

	return regmap_write_bits(data->regmap, MAX6639_REG_GCONFIG, MAX6639_GCONFIG_STANDBY,
				 ~MAX6639_GCONFIG_STANDBY);
}

static const struct i2c_device_id max6639_id[] = {
	{"max6639"},
	{ }
};

MODULE_DEVICE_TABLE(i2c, max6639_id);

static DEFINE_SIMPLE_DEV_PM_OPS(max6639_pm_ops, max6639_suspend, max6639_resume);

static const struct of_device_id max6639_of_match[] = {
	{ .compatible = "maxim,max6639", },
	{ },
};

static struct i2c_driver max6639_driver = {
	.class = I2C_CLASS_HWMON,
	.driver = {
		   .name = "max6639",
		   .pm = pm_sleep_ptr(&max6639_pm_ops),
		   .of_match_table = max6639_of_match,
		   },
	.probe = max6639_probe,
	.id_table = max6639_id,
	.detect = max6639_detect,
	.address_list = normal_i2c,
};

module_i2c_driver(max6639_driver);

MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>");
MODULE_DESCRIPTION("max6639 driver");
MODULE_LICENSE("GPL");
