[RFH] GMT G760A fan speed PWM controller

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, 10 Mar 2009 19:05:53 +0100 Martin Michlmayr <tbm at cyrius.com> wrote:

> From: Herbert Valerio Riedel <hvr at gnu.org>
> Subject: hwmon: add support for GMT G760A fan speed PWM controller
> 
> This controller can be found on the D-Link DNS-323 for instance,
> where it is to be configured via static i2c_board_info in the
> board-specific mach-orion/dns323-setup.c; this driver supports only
> the new-style driver model.
> 
>
> ...
>
> +struct g760a_data {
> +	struct i2c_client *client;
> +	struct device *hwmon_dev;
> +	struct mutex update_lock;
> +
> +	/* board specific parameters */
> +	u32 clk; /* default 32kHz */
> +	u16 fan_div; /* default P=2 */
> +
> +	/* g760a register cache */
> +	int valid:1;

I think sparse gets upset about signed single-bit bit fields.  Because the
sole bit is also the sign bit, so does it have a value of 1, or of -1???

So it should be converted to unsigned.

> +	unsigned long last_updated; /* In jiffies */
> +
> +	u8 set_cnt; /* PWM (period) count number; 0xff stops fan	*/
> +	u8 act_cnt; /*   formula: cnt = (CLK * 30)/(rpm * P)		*/
> +	u8 fan_sta; /* bit 0: set when actual fan speed more than 20%
> +		     *   outside requested fan speed
> +		     * bit 1: set when fan speed below 1920 rpm		*/
> +};
> +
> +#define G760A_DEFAULT_CLK 32768
> +#define G760A_DEFAULT_FAN_DIV 2
> +
> +#define RPM_FROM_CNT(val, clk, div) \
> +	((0x00 == (val)) ? 0 : (((clk)*30)/((val)*(div))))

The macro evaluates its arguments multiple times hence is slow or buggy if
passed an expression with side effects.

Please convert it to a plain old lower-case C function.

> +#define PWM_FROM_CNT(cnt)	(0xff-(cnt))
> +#define PWM_TO_CNT(pwm)		(0xff-(pwm))
> +
>
> ...
>
> +static ssize_t show_fan(struct device *dev, struct device_attribute *da,
> +			char *buf)
> +{
> +	struct g760a_data *data = g760a_update_client(dev);
> +	int rpm = 0;

An unsigned type would be more appropriate here.

> +	mutex_lock(&data->update_lock);
> +	if (!(data->fan_sta & G760A_REG_FAN_STA_RPM_LOW))
> +		rpm = RPM_FROM_CNT(data->act_cnt, data->clk, data->fan_div);
> +	mutex_unlock(&data->update_lock);
> +
> +	return sprintf(buf, "%d\n", rpm);
> +}
> +
>
> ...
>
> +static ssize_t set_pwm(struct device *dev, struct device_attribute *da,
> +		       const char *buf, size_t count)
> +{
> +	struct i2c_client *client = to_i2c_client(dev);
> +	struct g760a_data *data = g760a_update_client(dev);
> +
> +	const long val = simple_strtol(buf, NULL, 10);

strict_strtoul()?

> +	mutex_lock(&data->update_lock);
> +	data->set_cnt = PWM_TO_CNT(SENSORS_LIMIT(val, 0, 255));
> +	g760a_write_value(client, G760A_REG_SET_CNT, data->set_cnt);
> +	mutex_unlock(&data->update_lock);
> +
> +	return count;
> +}
> +
>
> ...
>




[Index of Archives]     [Linux Kernel]     [Linux Hardware Monitoring]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux