atxp1.c (f838bad1b3be8ca0c785ee0e0c570dfda74cf377) | atxp1.c (71163c7c36fa76bb5a72feca7fb685677444070a) |
---|---|
1/* 2 atxp1.c - kernel module for setting CPU VID and general purpose 3 I/Os using the Attansic ATXP1 chip. 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2 of the License, or 8 (at your option) any later version. --- 32 unchanged lines hidden (view full) --- 41#define ATXP1_VIDENA 0x20 42#define ATXP1_VIDMASK 0x1f 43#define ATXP1_GPIO1MASK 0x0f 44 45static const unsigned short normal_i2c[] = { 0x37, 0x4e, I2C_CLIENT_END }; 46 47I2C_CLIENT_INSMOD_1(atxp1); 48 | 1/* 2 atxp1.c - kernel module for setting CPU VID and general purpose 3 I/Os using the Attansic ATXP1 chip. 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2 of the License, or 8 (at your option) any later version. --- 32 unchanged lines hidden (view full) --- 41#define ATXP1_VIDENA 0x20 42#define ATXP1_VIDMASK 0x1f 43#define ATXP1_GPIO1MASK 0x0f 44 45static const unsigned short normal_i2c[] = { 0x37, 0x4e, I2C_CLIENT_END }; 46 47I2C_CLIENT_INSMOD_1(atxp1); 48 |
49static int atxp1_attach_adapter(struct i2c_adapter * adapter); 50static int atxp1_detach_client(struct i2c_client * client); | 49static int atxp1_probe(struct i2c_client *client, 50 const struct i2c_device_id *id); 51static int atxp1_remove(struct i2c_client *client); |
51static struct atxp1_data * atxp1_update_device(struct device *dev); | 52static struct atxp1_data * atxp1_update_device(struct device *dev); |
52static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind); | 53static int atxp1_detect(struct i2c_client *client, int kind, 54 struct i2c_board_info *info); |
53 | 55 |
56static const struct i2c_device_id atxp1_id[] = { 57 { "atxp1", atxp1 }, 58 { } 59}; 60MODULE_DEVICE_TABLE(i2c, atxp1_id); 61 |
|
54static struct i2c_driver atxp1_driver = { | 62static struct i2c_driver atxp1_driver = { |
63 .class = I2C_CLASS_HWMON, |
|
55 .driver = { 56 .name = "atxp1", 57 }, | 64 .driver = { 65 .name = "atxp1", 66 }, |
58 .attach_adapter = atxp1_attach_adapter, 59 .detach_client = atxp1_detach_client, | 67 .probe = atxp1_probe, 68 .remove = atxp1_remove, 69 .id_table = atxp1_id, 70 .detect = atxp1_detect, 71 .address_data = &addr_data, |
60}; 61 62struct atxp1_data { | 72}; 73 74struct atxp1_data { |
63 struct i2c_client client; | |
64 struct device *hwmon_dev; 65 struct mutex update_lock; 66 unsigned long last_updated; 67 u8 valid; 68 struct { 69 u8 vid; /* VID output register */ 70 u8 cpu_vid; /* VID input from CPU */ 71 u8 gpio1; /* General purpose I/O register 1 */ --- 186 unchanged lines hidden (view full) --- 258 NULL 259}; 260 261static const struct attribute_group atxp1_group = { 262 .attrs = atxp1_attributes, 263}; 264 265 | 75 struct device *hwmon_dev; 76 struct mutex update_lock; 77 unsigned long last_updated; 78 u8 valid; 79 struct { 80 u8 vid; /* VID output register */ 81 u8 cpu_vid; /* VID input from CPU */ 82 u8 gpio1; /* General purpose I/O register 1 */ --- 186 unchanged lines hidden (view full) --- 269 NULL 270}; 271 272static const struct attribute_group atxp1_group = { 273 .attrs = atxp1_attributes, 274}; 275 276 |
266static int atxp1_attach_adapter(struct i2c_adapter *adapter) | 277/* Return 0 if detection is successful, -ENODEV otherwise */ 278static int atxp1_detect(struct i2c_client *new_client, int kind, 279 struct i2c_board_info *info) |
267{ | 280{ |
268 if (!(adapter->class & I2C_CLASS_HWMON)) 269 return 0; 270 return i2c_probe(adapter, &addr_data, &atxp1_detect); 271}; | 281 struct i2c_adapter *adapter = new_client->adapter; |
272 | 282 |
273static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind) 274{ 275 struct i2c_client * new_client; 276 struct atxp1_data * data; 277 int err = 0; | |
278 u8 temp; 279 280 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 283 u8 temp; 284 285 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
281 goto exit; | 286 return -ENODEV; |
282 | 287 |
283 if (!(data = kzalloc(sizeof(struct atxp1_data), GFP_KERNEL))) { 284 err = -ENOMEM; 285 goto exit; 286 } 287 288 new_client = &data->client; 289 i2c_set_clientdata(new_client, data); 290 291 new_client->addr = address; 292 new_client->adapter = adapter; 293 new_client->driver = &atxp1_driver; 294 new_client->flags = 0; 295 | |
296 /* Detect ATXP1, checking if vendor ID registers are all zero */ 297 if (!((i2c_smbus_read_byte_data(new_client, 0x3e) == 0) && 298 (i2c_smbus_read_byte_data(new_client, 0x3f) == 0) && 299 (i2c_smbus_read_byte_data(new_client, 0xfe) == 0) && 300 (i2c_smbus_read_byte_data(new_client, 0xff) == 0) )) { 301 302 /* No vendor ID, now checking if registers 0x10,0x11 (non-existent) 303 * showing the same as register 0x00 */ 304 temp = i2c_smbus_read_byte_data(new_client, 0x00); 305 306 if (!((i2c_smbus_read_byte_data(new_client, 0x10) == temp) && 307 (i2c_smbus_read_byte_data(new_client, 0x11) == temp) )) | 288 /* Detect ATXP1, checking if vendor ID registers are all zero */ 289 if (!((i2c_smbus_read_byte_data(new_client, 0x3e) == 0) && 290 (i2c_smbus_read_byte_data(new_client, 0x3f) == 0) && 291 (i2c_smbus_read_byte_data(new_client, 0xfe) == 0) && 292 (i2c_smbus_read_byte_data(new_client, 0xff) == 0) )) { 293 294 /* No vendor ID, now checking if registers 0x10,0x11 (non-existent) 295 * showing the same as register 0x00 */ 296 temp = i2c_smbus_read_byte_data(new_client, 0x00); 297 298 if (!((i2c_smbus_read_byte_data(new_client, 0x10) == temp) && 299 (i2c_smbus_read_byte_data(new_client, 0x11) == temp) )) |
308 goto exit_free; | 300 return -ENODEV; |
309 } 310 311 /* Get VRM */ | 301 } 302 303 /* Get VRM */ |
312 data->vrm = vid_which_vrm(); | 304 temp = vid_which_vrm(); |
313 | 305 |
314 if ((data->vrm != 90) && (data->vrm != 91)) { 315 dev_err(&new_client->dev, "Not supporting VRM %d.%d\n", 316 data->vrm / 10, data->vrm % 10); 317 goto exit_free; | 306 if ((temp != 90) && (temp != 91)) { 307 dev_err(&adapter->dev, "atxp1: Not supporting VRM %d.%d\n", 308 temp / 10, temp % 10); 309 return -ENODEV; |
318 } 319 | 310 } 311 |
320 strncpy(new_client->name, "atxp1", I2C_NAME_SIZE); | 312 strlcpy(info->type, "atxp1", I2C_NAME_SIZE); |
321 | 313 |
322 data->valid = 0; | 314 return 0; 315} |
323 | 316 |
324 mutex_init(&data->update_lock); | 317static int atxp1_probe(struct i2c_client *new_client, 318 const struct i2c_device_id *id) 319{ 320 struct atxp1_data *data; 321 int err; |
325 | 322 |
326 err = i2c_attach_client(new_client); 327 328 if (err) 329 { 330 dev_err(&new_client->dev, "Attach client error.\n"); 331 goto exit_free; | 323 data = kzalloc(sizeof(struct atxp1_data), GFP_KERNEL); 324 if (!data) { 325 err = -ENOMEM; 326 goto exit; |
332 } 333 | 327 } 328 |
329 /* Get VRM */ 330 data->vrm = vid_which_vrm(); 331 332 i2c_set_clientdata(new_client, data); 333 data->valid = 0; 334 335 mutex_init(&data->update_lock); 336 |
|
334 /* Register sysfs hooks */ 335 if ((err = sysfs_create_group(&new_client->dev.kobj, &atxp1_group))) | 337 /* Register sysfs hooks */ 338 if ((err = sysfs_create_group(&new_client->dev.kobj, &atxp1_group))) |
336 goto exit_detach; | 339 goto exit_free; |
337 338 data->hwmon_dev = hwmon_device_register(&new_client->dev); 339 if (IS_ERR(data->hwmon_dev)) { 340 err = PTR_ERR(data->hwmon_dev); 341 goto exit_remove_files; 342 } 343 344 dev_info(&new_client->dev, "Using VRM: %d.%d\n", 345 data->vrm / 10, data->vrm % 10); 346 347 return 0; 348 349exit_remove_files: 350 sysfs_remove_group(&new_client->dev.kobj, &atxp1_group); | 340 341 data->hwmon_dev = hwmon_device_register(&new_client->dev); 342 if (IS_ERR(data->hwmon_dev)) { 343 err = PTR_ERR(data->hwmon_dev); 344 goto exit_remove_files; 345 } 346 347 dev_info(&new_client->dev, "Using VRM: %d.%d\n", 348 data->vrm / 10, data->vrm % 10); 349 350 return 0; 351 352exit_remove_files: 353 sysfs_remove_group(&new_client->dev.kobj, &atxp1_group); |
351exit_detach: 352 i2c_detach_client(new_client); | |
353exit_free: 354 kfree(data); 355exit: 356 return err; 357}; 358 | 354exit_free: 355 kfree(data); 356exit: 357 return err; 358}; 359 |
359static int atxp1_detach_client(struct i2c_client * client) | 360static int atxp1_remove(struct i2c_client *client) |
360{ 361 struct atxp1_data * data = i2c_get_clientdata(client); | 361{ 362 struct atxp1_data * data = i2c_get_clientdata(client); |
362 int err; | |
363 364 hwmon_device_unregister(data->hwmon_dev); 365 sysfs_remove_group(&client->dev.kobj, &atxp1_group); 366 | 363 364 hwmon_device_unregister(data->hwmon_dev); 365 sysfs_remove_group(&client->dev.kobj, &atxp1_group); 366 |
367 err = i2c_detach_client(client); | 367 kfree(data); |
368 | 368 |
369 if (err) 370 dev_err(&client->dev, "Failed to detach client.\n"); 371 else 372 kfree(data); 373 374 return err; | 369 return 0; |
375}; 376 377static int __init atxp1_init(void) 378{ 379 return i2c_add_driver(&atxp1_driver); 380}; 381 382static void __exit atxp1_exit(void) 383{ 384 i2c_del_driver(&atxp1_driver); 385}; 386 387module_init(atxp1_init); 388module_exit(atxp1_exit); | 370}; 371 372static int __init atxp1_init(void) 373{ 374 return i2c_add_driver(&atxp1_driver); 375}; 376 377static void __exit atxp1_exit(void) 378{ 379 i2c_del_driver(&atxp1_driver); 380}; 381 382module_init(atxp1_init); 383module_exit(atxp1_exit); |