18c2ecf20Sopenharmony_ci============== 28c2ecf20Sopenharmony_ciDevice Classes 38c2ecf20Sopenharmony_ci============== 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ciIntroduction 68c2ecf20Sopenharmony_ci~~~~~~~~~~~~ 78c2ecf20Sopenharmony_ciA device class describes a type of device, like an audio or network 88c2ecf20Sopenharmony_cidevice. The following device classes have been identified: 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci<Insert List of Device Classes Here> 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ciEach device class defines a set of semantics and a programming interface 148c2ecf20Sopenharmony_cithat devices of that class adhere to. Device drivers are the 158c2ecf20Sopenharmony_ciimplementation of that programming interface for a particular device on 168c2ecf20Sopenharmony_cia particular bus. 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ciDevice classes are agnostic with respect to what bus a device resides 198c2ecf20Sopenharmony_cion. 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ciProgramming Interface 238c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~ 248c2ecf20Sopenharmony_ciThe device class structure looks like:: 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci typedef int (*devclass_add)(struct device *); 288c2ecf20Sopenharmony_ci typedef void (*devclass_remove)(struct device *); 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ciSee the kerneldoc for the struct class. 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ciA typical device class definition would look like:: 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci struct device_class input_devclass = { 358c2ecf20Sopenharmony_ci .name = "input", 368c2ecf20Sopenharmony_ci .add_device = input_add_device, 378c2ecf20Sopenharmony_ci .remove_device = input_remove_device, 388c2ecf20Sopenharmony_ci }; 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ciEach device class structure should be exported in a header file so it 418c2ecf20Sopenharmony_cican be used by drivers, extensions and interfaces. 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ciDevice classes are registered and unregistered with the core using:: 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci int devclass_register(struct device_class * cls); 468c2ecf20Sopenharmony_ci void devclass_unregister(struct device_class * cls); 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ciDevices 508c2ecf20Sopenharmony_ci~~~~~~~ 518c2ecf20Sopenharmony_ciAs devices are bound to drivers, they are added to the device class 528c2ecf20Sopenharmony_cithat the driver belongs to. Before the driver model core, this would 538c2ecf20Sopenharmony_citypically happen during the driver's probe() callback, once the device 548c2ecf20Sopenharmony_cihas been initialized. It now happens after the probe() callback 558c2ecf20Sopenharmony_cifinishes from the core. 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ciThe device is enumerated in the class. Each time a device is added to 588c2ecf20Sopenharmony_cithe class, the class's devnum field is incremented and assigned to the 598c2ecf20Sopenharmony_cidevice. The field is never decremented, so if the device is removed 608c2ecf20Sopenharmony_cifrom the class and re-added, it will receive a different enumerated 618c2ecf20Sopenharmony_civalue. 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ciThe class is allowed to create a class-specific structure for the 648c2ecf20Sopenharmony_cidevice and store it in the device's class_data pointer. 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ciThere is no list of devices in the device class. Each driver has a 678c2ecf20Sopenharmony_cilist of devices that it supports. The device class has a list of 688c2ecf20Sopenharmony_cidrivers of that particular class. To access all of the devices in the 698c2ecf20Sopenharmony_ciclass, iterate over the device lists of each driver in the class. 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ciDevice Drivers 738c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~ 748c2ecf20Sopenharmony_ciDevice drivers are added to device classes when they are registered 758c2ecf20Sopenharmony_ciwith the core. A driver specifies the class it belongs to by setting 768c2ecf20Sopenharmony_cithe struct device_driver::devclass field. 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_cisysfs directory structure 808c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 818c2ecf20Sopenharmony_ciThere is a top-level sysfs directory named 'class'. 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ciEach class gets a directory in the class directory, along with two 848c2ecf20Sopenharmony_cidefault subdirectories:: 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci class/ 878c2ecf20Sopenharmony_ci `-- input 888c2ecf20Sopenharmony_ci |-- devices 898c2ecf20Sopenharmony_ci `-- drivers 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ciDrivers registered with the class get a symlink in the drivers/ directory 938c2ecf20Sopenharmony_cithat points to the driver's directory (under its bus directory):: 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci class/ 968c2ecf20Sopenharmony_ci `-- input 978c2ecf20Sopenharmony_ci |-- devices 988c2ecf20Sopenharmony_ci `-- drivers 998c2ecf20Sopenharmony_ci `-- usb:usb_mouse -> ../../../bus/drivers/usb_mouse/ 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ciEach device gets a symlink in the devices/ directory that points to the 1038c2ecf20Sopenharmony_cidevice's directory in the physical hierarchy:: 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci class/ 1068c2ecf20Sopenharmony_ci `-- input 1078c2ecf20Sopenharmony_ci |-- devices 1088c2ecf20Sopenharmony_ci | `-- 1 -> ../../../root/pci0/00:1f.0/usb_bus/00:1f.2-1:0/ 1098c2ecf20Sopenharmony_ci `-- drivers 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ciExporting Attributes 1138c2ecf20Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~ 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_ci:: 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci struct devclass_attribute { 1188c2ecf20Sopenharmony_ci struct attribute attr; 1198c2ecf20Sopenharmony_ci ssize_t (*show)(struct device_class *, char * buf, size_t count, loff_t off); 1208c2ecf20Sopenharmony_ci ssize_t (*store)(struct device_class *, const char * buf, size_t count, loff_t off); 1218c2ecf20Sopenharmony_ci }; 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ciClass drivers can export attributes using the DEVCLASS_ATTR macro that works 1248c2ecf20Sopenharmony_cisimilarly to the DEVICE_ATTR macro for devices. For example, a definition 1258c2ecf20Sopenharmony_cilike this:: 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_ci static DEVCLASS_ATTR(debug,0644,show_debug,store_debug); 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ciis equivalent to declaring:: 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci static devclass_attribute devclass_attr_debug; 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ciThe bus driver can add and remove the attribute from the class's 1348c2ecf20Sopenharmony_cisysfs directory using:: 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci int devclass_create_file(struct device_class *, struct devclass_attribute *); 1378c2ecf20Sopenharmony_ci void devclass_remove_file(struct device_class *, struct devclass_attribute *); 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ciIn the example above, the file will be named 'debug' in placed in the 1408c2ecf20Sopenharmony_ciclass's directory in sysfs. 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ciInterfaces 1448c2ecf20Sopenharmony_ci~~~~~~~~~~ 1458c2ecf20Sopenharmony_ciThere may exist multiple mechanisms for accessing the same device of a 1468c2ecf20Sopenharmony_ciparticular class type. Device interfaces describe these mechanisms. 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ciWhen a device is added to a device class, the core attempts to add it 1498c2ecf20Sopenharmony_cito every interface that is registered with the device class. 150