unsigned int freq_in, unsigned int freq_out);
 
        /* codec IO */
+       struct regmap *(*get_regmap)(struct device *);
        unsigned int (*read)(struct snd_soc_codec *, unsigned int);
        int (*write)(struct snd_soc_codec *, unsigned int, unsigned int);
        int (*display_register)(struct snd_soc_codec *, char *,
 
 
        codec->dapm.idle_bias_off = driver->idle_bias_off;
 
-       if (!codec->write && dev_get_regmap(codec->dev, NULL)) {
-               /* Set the default I/O up try regmap */
-               ret = snd_soc_codec_set_cache_io(codec, NULL);
-               if (ret < 0) {
-                       dev_err(codec->dev,
-                               "Failed to set cache I/O: %d\n", ret);
-                       goto err_probe;
-               }
-       }
-
        if (driver->probe) {
                ret = driver->probe(codec);
                if (ret < 0) {
                           int num_dai)
 {
        struct snd_soc_codec *codec;
+       struct regmap *regmap;
        int ret, i;
 
        dev_dbg(dev, "codec register %s\n", dev_name(dev));
        codec->num_dai = num_dai;
        mutex_init(&codec->mutex);
 
+       if (!codec->write) {
+               if (codec_drv->get_regmap)
+                       regmap = codec_drv->get_regmap(dev);
+               else
+                       regmap = dev_get_regmap(dev, NULL);
+
+               if (regmap) {
+                       ret = snd_soc_codec_set_cache_io(codec, regmap);
+                       if (ret && ret != -ENOTSUPP) {
+                               dev_err(codec->dev,
+                                               "Failed to set cache I/O:%d\n",
+                                               ret);
+                               return ret;
+                       }
+               }
+       }
+
        for (i = 0; i < num_dai; i++) {
                fixup_codec_formats(&dai_drv[i].playback);
                fixup_codec_formats(&dai_drv[i].capture);
 
 {
        int ret;
 
-       /* Device has made its own regmap arrangements */
        if (!regmap)
-               codec->control_data = dev_get_regmap(codec->dev, NULL);
-       else
-               codec->control_data = regmap;
+               return -EINVAL;
 
-       if (IS_ERR(codec->control_data))
-               return PTR_ERR(codec->control_data);
+       /* Device has made its own regmap arrangements */
+       codec->control_data = regmap;
 
        codec->write = hw_write;
        codec->read = hw_read;