+#ifndef __COMPAT_H
+#define __COMPAT_H
+
+#include <linux/version.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16)
+#error This driver is for kernel versions 2.6.16 and later
+#endif
+
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 21)
+#if !(defined RHEL_MAJOR && RHEL_MAJOR == 5 && RHEL_MINOR >= 6)
+/* Simplified version for compatibility */
+struct i2c_board_info {
+ char type[I2C_NAME_SIZE];
+ unsigned short flags;
+ unsigned short addr;
+};
+#endif
+#endif
+
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 25)
+/* Some older kernels have a different, useless struct i2c_device_id */
+#define i2c_device_id i2c_device_id_compat
+struct i2c_device_id {
+ char name[I2C_NAME_SIZE];
+ kernel_ulong_t driver_data /* Data private to the driver */
+ __attribute__((aligned(sizeof(kernel_ulong_t))));
+};
+#endif
+
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 32)
+static unsigned short empty_i2c[] = { I2C_CLIENT_END };
+static struct i2c_client_address_data addr_data = {
+ .normal_i2c = normal_i2c,
+ .probe = empty_i2c,
+ .ignore = empty_i2c,
+};
+#endif
+
+/* Red Hat EL5 includes backports of these functions, so we can't redefine
+ * our own. */
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
+#if !(defined RHEL_MAJOR && RHEL_MAJOR == 5 && RHEL_MINOR >= 5)
+static inline int strict_strtoul(const char *cp, unsigned int base,
+ unsigned long *res)
+{
+ *res = simple_strtoul(cp, NULL, base);
+ return 0;
+}
+
+static inline int strict_strtol(const char *cp, unsigned int base, long *res)
+{
+ *res = simple_strtol(cp, NULL, base);
+ return 0;
+}
+#endif
+#endif
+
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 28)
+/*
+ * Divide positive or negative dividend by positive divisor and round
+ * to closest integer. Result is undefined for negative divisors and
+ * for negative dividends if the divisor variable type is unsigned.
+ */
+#define DIV_ROUND_CLOSEST(x, divisor)( \
+{ \
+ typeof(x) __x = x; \
+ typeof(divisor) __d = divisor; \
+ (((typeof(x))-1) > 0 || \
+ ((typeof(divisor))-1) > 0 || (__x) > 0) ? \
+ (((__x) + ((__d) / 2)) / (__d)) : \
+ (((__x) - ((__d) / 2)) / (__d)); \
+} \
+)
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)
+static inline s32
+i2c_smbus_read_word_swapped(const struct i2c_client *client, u8 command)
+{
+ s32 value = i2c_smbus_read_word_data(client, command);
+
+ return (value < 0) ? value : swab16(value);
+}
+
+static inline s32
+i2c_smbus_write_word_swapped(const struct i2c_client *client,
+ u8 command, u16 value)
+{
+ return i2c_smbus_write_word_data(client, command, swab16(value));
+}
+#endif
+
+#ifndef module_driver
+/**
+ * module_driver() - Helper macro for drivers that don't do anything
+ * special in module init/exit. This eliminates a lot of boilerplate.
+ * Each module may only use this macro once, and calling it replaces
+ * module_init() and module_exit().
+ *
+ * @__driver: driver name
+ * @__register: register function for this driver type
+ * @__unregister: unregister function for this driver type
+ * @...: Additional arguments to be passed to __register and __unregister.