linux/drivers/clk/idt/clk-idt8t49n24x.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* clk-idt8t49n24x.c - Program 8T49N24x settings via I2C.
   3 *
   4 * Copyright (C) 2018, Integrated Device Technology, Inc. <david.cater@idt.com>
   5 *
   6 * See https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html
   7 * This program is distributed "AS IS" and  WITHOUT ANY WARRANTY;
   8 * including the implied warranties of MERCHANTABILITY, FITNESS FOR
   9 * A PARTICULAR PURPOSE, or NON-INFRINGEMENT.
  10 */
  11
  12#include <linux/i2c.h>
  13#include <linux/module.h>
  14#include <linux/slab.h>
  15
  16#include "clk-idt8t49n24x-core.h"
  17#include "clk-idt8t49n24x-debugfs.h"
  18
  19#define OUTPUTMODE_HIGHZ        0
  20#define OUTPUTMODE_LVDS         2
  21#define IDT24x_MIN_FREQ         1000000L
  22#define IDT24x_MAX_FREQ         300000000L
  23#define DRV_NAME                "idt8t49n24x"
  24
  25enum clk_idt24x_variant {
  26        idt24x
  27};
  28
  29static u32 mask_and_shift(u32 value, u8 mask)
  30{
  31        value &= mask;
  32        return value >> bits_to_shift(mask);
  33}
  34
  35/**
  36 * idt24x_set_output_mode - Set the mode for a particular clock
  37 * output in the register.
  38 * @reg:        The current register value before setting the mode.
  39 * @mask:       The bitmask identifying where in the register the
  40 *              output mode is stored.
  41 * @mode:       The mode to set.
  42 *
  43 * Return: the new register value with the specified mode bits set.
  44 */
  45static int idt24x_set_output_mode(u32 reg, u8 mask, u8 mode)
  46{
  47        if (((reg & mask) >> bits_to_shift(mask)) == OUTPUTMODE_HIGHZ) {
  48                reg = reg & ~mask;
  49                reg |= (OUTPUTMODE_LVDS << bits_to_shift(mask));
  50        }
  51        return reg;
  52}
  53
  54/**
  55 * idt24x_read_from_hw - Get the current values on the hw
  56 * @chip:       Device data structure
  57 *
  58 * Return: 0 on success, negative errno otherwise.
  59 */
  60static int idt24x_read_from_hw(struct clk_idt24x_chip *chip)
  61{
  62        int err;
  63        struct i2c_client *client = chip->i2c_client;
  64        u32 tmp, tmp2;
  65        u8 output;
  66
  67        err = regmap_read(chip->regmap, IDT24x_REG_DSM_INT_8,
  68                          &chip->reg_dsm_int_8);
  69        if (err) {
  70                dev_err(&client->dev,
  71                        "%s: error reading IDT24x_REG_DSM_INT_8: %i",
  72                        __func__, err);
  73                return err;
  74        }
  75        dev_dbg(&client->dev, "%s: reg_dsm_int_8: 0x%x",
  76                __func__, chip->reg_dsm_int_8);
  77
  78        err = regmap_read(chip->regmap, IDT24x_REG_DSMFRAC_20_16_MASK,
  79                          &chip->reg_dsm_frac_20_16);
  80        if (err) {
  81                dev_err(&client->dev,
  82                        "%s: error reading IDT24x_REG_DSMFRAC_20_16_MASK: %i",
  83                        __func__, err);
  84                return err;
  85        }
  86        dev_dbg(&client->dev, "%s: reg_dsm_frac_20_16: 0x%x",
  87                __func__, chip->reg_dsm_frac_20_16);
  88
  89        err = regmap_read(chip->regmap, IDT24x_REG_OUTEN, &chip->reg_out_en_x);
  90        if (err) {
  91                dev_err(&client->dev,
  92                        "%s: error reading IDT24x_REG_OUTEN: %i",
  93                        __func__, err);
  94                return err;
  95        }
  96        dev_dbg(&client->dev, "%s: reg_out_en_x: 0x%x",
  97                __func__, chip->reg_out_en_x);
  98
  99        err = regmap_read(chip->regmap, IDT24x_REG_OUTMODE0_1, &tmp);
 100        if (err) {
 101                dev_err(&client->dev,
 102                        "%s: error reading IDT24x_REG_OUTMODE0_1: %i",
 103                        __func__, err);
 104                return err;
 105        }
 106
 107        tmp2 = idt24x_set_output_mode(
 108                tmp, IDT24x_REG_OUTMODE0_MASK, OUTPUTMODE_LVDS);
 109        tmp2 = idt24x_set_output_mode(
 110                tmp2, IDT24x_REG_OUTMODE1_MASK, OUTPUTMODE_LVDS);
 111        dev_dbg(&client->dev,
 112                "%s: reg_out_mode_0_1 original: 0x%x. After setting OUT0/1 to LVDS if necessary: 0x%x",
 113                __func__, tmp, tmp2);
 114        chip->reg_out_mode_0_1 = tmp2;
 115
 116        err = regmap_read(chip->regmap, IDT24x_REG_OUTMODE2_3, &tmp);
 117        if (err) {
 118                dev_err(&client->dev,
 119                        "%s: error reading IDT24x_REG_OUTMODE2_3: %i",
 120                        __func__, err);
 121                return err;
 122        }
 123
 124        tmp2 = idt24x_set_output_mode(
 125                tmp, IDT24x_REG_OUTMODE2_MASK, OUTPUTMODE_LVDS);
 126        tmp2 = idt24x_set_output_mode(
 127                tmp2, IDT24x_REG_OUTMODE3_MASK, OUTPUTMODE_LVDS);
 128        dev_dbg(&client->dev,
 129                "%s: reg_out_mode_2_3 original: 0x%x. After setting OUT2/3 to LVDS if necessary: 0x%x",
 130                __func__, tmp, tmp2);
 131        chip->reg_out_mode_2_3 = tmp2;
 132
 133        err = regmap_read(chip->regmap, IDT24x_REG_Q_DIS, &chip->reg_qx_dis);
 134        if (err) {
 135                dev_err(&client->dev,
 136                        "%s: error reading IDT24x_REG_Q_DIS: %i",
 137                        __func__, err);
 138                return err;
 139        }
 140        dev_dbg(&client->dev, "%s: reg_qx_dis: 0x%x",
 141                __func__, chip->reg_qx_dis);
 142
 143        err = regmap_read(chip->regmap, IDT24x_REG_NS1_Q0, &chip->reg_ns1_q0);
 144        if (err) {
 145                dev_err(&client->dev,
 146                        "%s: error reading IDT24x_REG_NS1_Q0: %i",
 147                        __func__, err);
 148                return err;
 149        }
 150        dev_dbg(&client->dev, "%s: reg_ns1_q0: 0x%x",
 151                __func__, chip->reg_ns1_q0);
 152
 153        for (output = 1; output <= 3; output++) {
 154                struct clk_register_offsets offsets;
 155
 156                err = idt24x_get_offsets(output, &offsets);
 157                if (err) {
 158                        dev_err(&client->dev,
 159                                "%s: error calling idt24x_get_offsets: %i",
 160                                __func__, err);
 161                        return err;
 162                }
 163
 164                err = regmap_read(chip->regmap, offsets.n_17_16_offset,
 165                                  &chip->reg_n_qx_17_16[output - 1]);
 166                if (err) {
 167                        dev_err(&client->dev,
 168                                "%s: error reading n_17_16_offset for output %d (offset: 0x%x): %i",
 169                                __func__, output, offsets.n_17_16_offset, err);
 170                        return err;
 171                }
 172                dev_dbg(&client->dev,
 173                        "%s: reg_n_qx_17_16[Q%u]: 0x%x",
 174                        __func__, output, chip->reg_n_qx_17_16[output - 1]);
 175
 176                err = regmap_read(chip->regmap, offsets.nfrac_27_24_offset,
 177                                  &chip->reg_nfrac_qx_27_24[output - 1]);
 178                if (err) {
 179                        dev_err(&client->dev,
 180                                "%s: error reading nfrac_27_24_offset for output %d (offset: 0x%x): %i",
 181                                __func__, output,
 182                                offsets.nfrac_27_24_offset, err);
 183                        return err;
 184                }
 185                dev_dbg(&client->dev,
 186                        "%s: reg_nfrac_qx_27_24[Q%u]: 0x%x",
 187                        __func__, output,
 188                        chip->reg_nfrac_qx_27_24[output - 1]);
 189        }
 190
 191        dev_info(&client->dev,
 192                 "%s: initial values read from chip successfully",
 193                 __func__);
 194
 195        /* Also read DBL_DIS to determine whether the doubler is disabled. */
 196        err = regmap_read(chip->regmap, IDT24x_REG_DBL_DIS, &tmp);
 197        if (err) {
 198                dev_err(&client->dev,
 199                        "%s: error reading IDT24x_REG_DBL_DIS: %i",
 200                        __func__, err);
 201                return err;
 202        }
 203        chip->doubler_disabled = mask_and_shift(tmp, IDT24x_REG_DBL_DIS_MASK);
 204        dev_dbg(&client->dev, "%s: doubler_disabled: %d",
 205                __func__, chip->doubler_disabled);
 206
 207        return 0;
 208}
 209
 210/**
 211 * idt24x_set_rate - Sets the specified output clock to the specified rate.
 212 * @hw:         clk_hw struct that identifies the specific output clock.
 213 * @rate:       the rate (in Hz) for the specified clock.
 214 * @parent_rate:(not sure) the rate for a parent signal (e.g.,
 215 *              the VCO feeding the output)
 216 *
 217 * This function will call idt24_set_frequency, which means it will
 218 * calculate divider for all requested outputs and update the attached
 219 * device (issue I2C commands to update the registers).
 220 *
 221 * Return: 0 on success.
 222 */
 223static int idt24x_set_rate(struct clk_hw *hw, unsigned long rate,
 224                           unsigned long parent_rate)
 225{
 226        int err = 0;
 227
 228        /*
 229         * hw->clk is the pointer to the specific output clock the user is
 230         * requesting. We use hw to get back to the output structure for
 231         * the output clock. Set the requested rate in the output structure.
 232         * Note that container_of cannot be used to find the device structure
 233         * (clk_idt24x_chip) from clk_hw, because clk_idt24x_chip has an array
 234         * of idt24x_output structs. That is why it is necessary to use
 235         * output->chip to access the device structure.
 236         */
 237        struct idt24x_output *output = to_idt24x_output(hw);
 238        struct i2c_client *client = output->chip->i2c_client;
 239
 240        if (rate < output->chip->min_freq || rate > output->chip->max_freq) {
 241                dev_err(&client->dev,
 242                        "requested frequency (%luHz) is out of range\n", rate);
 243                return -EINVAL;
 244        }
 245
 246        /*
 247         * Set the requested frequency in the output data structure, and then
 248         * call idt24x_set_frequency. idt24x_set_frequency considers all
 249         * requested frequencies when deciding on a vco frequency and
 250         * calculating dividers.
 251         */
 252        output->requested = rate;
 253
 254        /*
 255         * Also set in the memory location used by the debugfs file
 256         * that exposes the output clock frequency. That allows querying
 257         * the current rate via debugfs.
 258         */
 259        output->debug_freq = rate;
 260
 261        dev_info(&client->dev,
 262                 "%s. calling idt24x_set_frequency for Q%u. rate: %lu",
 263                 __func__, output->index, rate);
 264        err = idt24x_set_frequency(output->chip);
 265
 266        if (err != 0)
 267                dev_err(&client->dev, "error calling set_frequency: %d", err);
 268
 269        return err;
 270}
 271
 272/**
 273 * idt24x_round_rate - get valid rate that is closest to the requested rate
 274 * @hw:         clk_hw struct that identifies the specific output clock.
 275 * @rate:       the rate (in Hz) for the specified clock.
 276 * @parent_rate:(not sure) the rate for a parent signal (e.g., the VCO
 277 *              feeding the output). This is an i/o param.
 278 *              If the driver supports a parent clock for the output (e.g.,
 279 *              the VCO(?), then set this param to indicate what the rate of
 280 *              the parent would be (e.g., the VCO frequency) if the rounded
 281 *              rate is used.
 282 *
 283 * Returns the closest rate to the requested rate actually supported by the
 284 * chip.
 285 *
 286 * Return: adjusted rate
 287 */
 288static long idt24x_round_rate(struct clk_hw *hw, unsigned long rate,
 289                              unsigned long *parent_rate)
 290{
 291        /*
 292         * The chip has fractional output dividers, so assume it
 293         * can provide the requested rate.
 294         *
 295         * TODO: figure out the closest rate that chip can support
 296         * within a low error threshold and return that rate.
 297         */
 298        return rate;
 299}
 300
 301/**
 302 * idt24x_recalc_rate - return the frequency being provided by the clock.
 303 * @hw:                 clk_hw struct that identifies the specific output clock.
 304 * @parent_rate:        (not sure) the rate for a parent signal (e.g., the
 305 *                      VCO feeding the output)
 306 *
 307 * This API appears to be used to read the current values from the hardware
 308 * and report the frequency being provided by the clock. Without this function,
 309 * the clock will be initialized to 0 by default. The OS appears to be
 310 * calling this to find out what the current value of the clock is at
 311 * startup, so it can determine when .set_rate is actually changing the
 312 * frequency.
 313 *
 314 * Return: the frequency of the specified clock.
 315 */
 316static unsigned long idt24x_recalc_rate(struct clk_hw *hw,
 317                                        unsigned long parent_rate)
 318{
 319        struct idt24x_output *output = to_idt24x_output(hw);
 320
 321        return output->requested;
 322}
 323
 324/*
 325 * Note that .prepare and .unprepare appear to be used more in Gates.
 326 * They do not appear to be necessary for this device.
 327 * Instead, update the device when .set_rate is called.
 328 */
 329static const struct clk_ops idt24x_clk_ops = {
 330        .recalc_rate = idt24x_recalc_rate,
 331        .round_rate = idt24x_round_rate,
 332        .set_rate = idt24x_set_rate,
 333};
 334
 335static bool idt24x_regmap_is_volatile(struct device *dev, unsigned int reg)
 336{
 337        return false;
 338}
 339
 340static bool idt24x_regmap_is_writeable(struct device *dev, unsigned int reg)
 341{
 342        return true;
 343}
 344
 345static const struct regmap_config idt24x_regmap_config = {
 346        .reg_bits = 16,
 347        .val_bits = 8,
 348        .cache_type = REGCACHE_RBTREE,
 349        .max_register = 0xffff,
 350        .writeable_reg = idt24x_regmap_is_writeable,
 351        .volatile_reg = idt24x_regmap_is_volatile,
 352};
 353
 354/**
 355 * idt24x_clk_notifier_cb - Clock rate change callback
 356 * @nb:         Pointer to notifier block
 357 * @event:      Notification reason
 358 * @data:       Pointer to notification data object
 359 *
 360 * This function is called when the input clock frequency changes.
 361 * The callback checks whether a valid bus frequency can be generated after the
 362 * change. If so, the change is acknowledged, otherwise the change is aborted.
 363 * New dividers are written to the HW in the pre- or post change notification
 364 * depending on the scaling direction.
 365 *
 366 * Return:      NOTIFY_STOP if the rate change should be aborted, NOTIFY_OK
 367 *              to acknowledge the change, NOTIFY_DONE if the notification is
 368 *              considered irrelevant.
 369 */
 370static int idt24x_clk_notifier_cb(struct notifier_block *nb,
 371                                  unsigned long event, void *data)
 372{
 373        struct clk_notifier_data *ndata = data;
 374        struct clk_idt24x_chip *chip = to_clk_idt24x_from_nb(nb);
 375        int err = 0;
 376
 377        dev_info(&chip->i2c_client->dev,
 378                 "%s: input frequency changed: %lu Hz. event: %lu",
 379                 __func__, ndata->new_rate, event);
 380
 381        switch (event) {
 382        case PRE_RATE_CHANGE: {
 383                dev_dbg(&chip->i2c_client->dev, "PRE_RATE_CHANGE\n");
 384                return NOTIFY_OK;
 385        }
 386        case POST_RATE_CHANGE:
 387                chip->input_clk_freq = ndata->new_rate;
 388                /*
 389                 * Can't call clock API clk_set_rate here; I believe
 390                 * it will be ignored if the rate is the same as we
 391                 * set previously. Need to call our internal function.
 392                 */
 393                dev_dbg(&chip->i2c_client->dev,
 394                        "POST_RATE_CHANGE. Calling idt24x_set_frequency\n");
 395                err = idt24x_set_frequency(chip);
 396                if (err)
 397                        dev_err(&chip->i2c_client->dev,
 398                                "error calling idt24x_set_frequency (%i)\n",
 399                                err);
 400                return NOTIFY_OK;
 401        case ABORT_RATE_CHANGE:
 402                return NOTIFY_OK;
 403        default:
 404                return NOTIFY_DONE;
 405        }
 406}
 407
 408static struct clk_hw *of_clk_idt24x_get(
 409        struct of_phandle_args *clkspec, void *_data)
 410{
 411        struct clk_idt24x_chip *chip = _data;
 412        unsigned int idx = clkspec->args[0];
 413
 414        if (idx >= ARRAY_SIZE(chip->clk)) {
 415                pr_err("%s: invalid index %u\n", __func__, idx);
 416                return ERR_PTR(-EINVAL);
 417        }
 418
 419        return &chip->clk[idx].hw;
 420}
 421
 422/**
 423 * idt24x_probe - main entry point for ccf driver
 424 * @client:     pointer to i2c_client structure
 425 * @id:         pointer to i2c_device_id structure
 426 *
 427 * Main entry point function that gets called to initialize the driver.
 428 *
 429 * Return: 0 for success.
 430 */
 431static int idt24x_probe(struct i2c_client *client,
 432                        const struct i2c_device_id *id)
 433{
 434        struct clk_idt24x_chip *chip;
 435        struct clk_init_data init;
 436
 437        int err = 0;
 438        int x;
 439        char buf[6];
 440
 441        dev_info(&client->dev, "%s", __func__);
 442        chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
 443        if (!chip)
 444                return -ENOMEM;
 445
 446        init.ops = &idt24x_clk_ops;
 447        init.flags = 0;
 448        init.num_parents = 0;
 449        chip->i2c_client = client;
 450
 451        chip->min_freq = IDT24x_MIN_FREQ;
 452        chip->max_freq = IDT24x_MAX_FREQ;
 453
 454        for (x = 0; x < NUM_INPUTS + 1; x++) {
 455                char name[12];
 456
 457                sprintf(name, x == NUM_INPUTS ? "input-xtal" : "input-clk%i",
 458                        x);
 459                dev_dbg(&client->dev, "attempting to get %s", name);
 460                chip->input_clk = devm_clk_get(&client->dev, name);
 461                if (IS_ERR(chip->input_clk)) {
 462                        err = PTR_ERR(chip->input_clk);
 463                        /*
 464                         * TODO: Handle EPROBE_DEFER error, which indicates
 465                         * that the input_clk isn't available now but may be
 466                         * later when the appropriate module is loaded.
 467                         */
 468                } else {
 469                        err = 0;
 470                        chip->input_clk_num = x;
 471                        break;
 472                }
 473        }
 474
 475        if (err) {
 476                dev_err(&client->dev, "Unable to get input clock (%u).", err);
 477                chip->input_clk = NULL;
 478                return err;
 479        }
 480
 481        chip->input_clk_freq = clk_get_rate(chip->input_clk);
 482        dev_dbg(&client->dev, "Got input-freq from input-clk in device tree: %uHz",
 483                chip->input_clk_freq);
 484
 485        chip->input_clk_nb.notifier_call = idt24x_clk_notifier_cb;
 486        if (clk_notifier_register(chip->input_clk, &chip->input_clk_nb))
 487                dev_warn(&client->dev,
 488                         "Unable to register clock notifier for input_clk.");
 489
 490        dev_dbg(&client->dev, "%s: about to read settings: %zu",
 491                __func__, ARRAY_SIZE(chip->settings));
 492
 493        err = of_property_read_u8_array(
 494                client->dev.of_node, "settings", chip->settings,
 495                ARRAY_SIZE(chip->settings));
 496        if (!err) {
 497                dev_dbg(&client->dev, "settings property specified in DT");
 498                chip->has_settings = true;
 499        } else {
 500                if (err == -EOVERFLOW) {
 501                        dev_alert(&client->dev,
 502                                  "EOVERFLOW error trying to read the settings. ARRAY_SIZE: %zu",
 503                                  ARRAY_SIZE(chip->settings));
 504                        return err;
 505                }
 506                dev_dbg(&client->dev,
 507                        "settings property not specified in DT (or there was an error that can be ignored: %i). The settings property is optional.",
 508                        err);
 509        }
 510
 511        /*
 512         * Requested output frequencies cannot be specified in the DT.
 513         * Either a consumer needs to use the clock API to request the rate,
 514         * or use debugfs to set the rate from user space. Use clock-names in
 515         * DT to specify the output clock.
 516         */
 517
 518        chip->regmap = devm_regmap_init_i2c(client, &idt24x_regmap_config);
 519        if (IS_ERR(chip->regmap)) {
 520                dev_err(&client->dev, "failed to allocate register map\n");
 521                return PTR_ERR(chip->regmap);
 522        }
 523
 524        dev_dbg(&client->dev, "%s: call i2c_set_clientdata", __func__);
 525        i2c_set_clientdata(client, chip);
 526
 527        if (chip->has_settings) {
 528                /*
 529                 * A raw settings array was specified in the DT. Write the
 530                 * settings to the device immediately.
 531                 */
 532                err = i2cwritebulk(
 533                        chip->i2c_client, chip->regmap, 0, chip->settings,
 534                        ARRAY_SIZE(chip->settings));
 535                if (err) {
 536                        dev_err(&client->dev,
 537                                "error writing all settings to chip (%i)\n",
 538                                err);
 539                        return err;
 540                }
 541                dev_dbg(&client->dev, "successfully wrote full settings array");
 542        }
 543
 544        /*
 545         * Whether or not settings were written to the device, read all
 546         * current values from the hw.
 547         */
 548        dev_dbg(&client->dev, "read from HW");
 549        err = idt24x_read_from_hw(chip);
 550        if (err) {
 551                dev_err(&client->dev,
 552                        "failed calling idt24x_read_from_hw (%i)\n", err);
 553                return err;
 554        }
 555
 556        /* Create all 4 clocks */
 557        for (x = 0; x < NUM_OUTPUTS; x++) {
 558                init.name = kasprintf(
 559                        GFP_KERNEL, "%s.Q%i", client->dev.of_node->name, x);
 560                chip->clk[x].chip = chip;
 561                chip->clk[x].hw.init = &init;
 562                chip->clk[x].index = x;
 563                err = devm_clk_hw_register(&client->dev, &chip->clk[x].hw);
 564                kfree(init.name); /* clock framework made a copy of the name */
 565                if (err) {
 566                        dev_err(&client->dev, "clock registration failed\n");
 567                        return err;
 568                }
 569                dev_dbg(&client->dev, "successfully registered Q%i", x);
 570        }
 571
 572        if (err) {
 573                dev_err(&client->dev, "clock registration failed\n");
 574                return err;
 575        }
 576
 577        err = of_clk_add_hw_provider(
 578                client->dev.of_node, of_clk_idt24x_get, chip);
 579        if (err) {
 580                dev_err(&client->dev, "unable to add clk provider\n");
 581                return err;
 582        }
 583
 584        err = idt24x_expose_via_debugfs(client, chip);
 585        if (err) {
 586                dev_err(&client->dev,
 587                        "error calling idt24x_expose_via_debugfs: %i\n", err);
 588                return err;
 589        }
 590
 591        if (chip->input_clk_num == NUM_INPUTS)
 592                sprintf(buf, "XTAL");
 593        else
 594                sprintf(buf, "CLK%i", chip->input_clk_num);
 595        dev_info(&client->dev, "probe success. input freq: %uHz (%s), settings string? %s\n",
 596                 chip->input_clk_freq, buf,
 597                 chip->has_settings ? "true" : "false");
 598        return 0;
 599}
 600
 601static int idt24x_remove(struct i2c_client *client)
 602{
 603        struct clk_idt24x_chip *chip = to_clk_idt24x_from_client(&client);
 604
 605        dev_info(&client->dev, "%s", __func__);
 606        of_clk_del_provider(client->dev.of_node);
 607        idt24x_cleanup_debugfs(chip);
 608
 609        if (!chip->input_clk)
 610                clk_notifier_unregister(
 611                        chip->input_clk, &chip->input_clk_nb);
 612        return 0;
 613}
 614
 615static const struct i2c_device_id idt24x_id[] = {
 616        { "idt8t49n24x", idt24x },
 617        { }
 618};
 619MODULE_DEVICE_TABLE(i2c, idt24x_id);
 620
 621static const struct of_device_id idt24x_of_match[] = {
 622        { .compatible = "idt,idt8t49n241" },
 623        {},
 624};
 625MODULE_DEVICE_TABLE(of, idt24x_of_match);
 626
 627static struct i2c_driver idt24x_driver = {
 628        .driver = {
 629                .name = DRV_NAME,
 630                .of_match_table = idt24x_of_match,
 631        },
 632        .probe = idt24x_probe,
 633        .remove = idt24x_remove,
 634        .id_table = idt24x_id,
 635};
 636
 637module_i2c_driver(idt24x_driver);
 638
 639MODULE_DESCRIPTION("8T49N24x ccf driver");
 640MODULE_AUTHOR("David Cater <david.cater@idt.com>");
 641MODULE_LICENSE("GPL v2");
 642