1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
4  */
5 /*
6  * infrastructure for devices connected via I2C
7  */
8 
9 #include <linux/slab.h>
10 #include "via_aux.h"
11 
12 
via_aux_probe(struct i2c_adapter * adap)13 struct via_aux_bus *via_aux_probe(struct i2c_adapter *adap)
14 {
15 	struct via_aux_bus *bus;
16 
17 	if (!adap)
18 		return NULL;
19 
20 	bus = kmalloc(sizeof(*bus), GFP_KERNEL);
21 	if (!bus)
22 		return NULL;
23 
24 	bus->adap = adap;
25 	INIT_LIST_HEAD(&bus->drivers);
26 
27 	via_aux_edid_probe(bus);
28 	via_aux_vt1636_probe(bus);
29 	via_aux_vt1632_probe(bus);
30 	via_aux_vt1631_probe(bus);
31 	via_aux_vt1625_probe(bus);
32 	via_aux_vt1622_probe(bus);
33 	via_aux_vt1621_probe(bus);
34 	via_aux_sii164_probe(bus);
35 	via_aux_ch7301_probe(bus);
36 
37 	return bus;
38 }
39 
via_aux_free(struct via_aux_bus * bus)40 void via_aux_free(struct via_aux_bus *bus)
41 {
42 	struct via_aux_drv *pos, *n;
43 
44 	if (!bus)
45 		return;
46 
47 	list_for_each_entry_safe(pos, n, &bus->drivers, chain) {
48 		if (pos->cleanup)
49 			pos->cleanup(pos);
50 
51 		list_del(&pos->chain);
52 		kfree(pos->data);
53 		kfree(pos);
54 	}
55 
56 	kfree(bus);
57 }
58 
via_aux_get_preferred_mode(struct via_aux_bus * bus)59 const struct fb_videomode *via_aux_get_preferred_mode(struct via_aux_bus *bus)
60 {
61 	struct via_aux_drv *pos;
62 	const struct fb_videomode *mode = NULL;
63 
64 	if (!bus)
65 		return NULL;
66 
67 	list_for_each_entry(pos, &bus->drivers, chain) {
68 		if (pos->get_preferred_mode)
69 			mode = pos->get_preferred_mode(pos);
70 	}
71 
72 	return mode;
73 }
74